c# - 多态性和依赖注入,如何在不实例化的情况下选择子类
问题描述
对于 DI,我一直使用的方法是构造函数注入。同样使用DI,依赖类被注入到调用类中,不需要实例化依赖类。
考虑下面的这段代码,我需要确定要使用哪个具体类。如何在不手动实例化类的情况下选择正确的具体类(因为使用 DI,注入器会为您完成)?代码都是手写的,请原谅任何错字:)
public interface IMyInterface
{
void DoSomething();
}
public class SuperClass : IMyInterface
{
private DependencyClass _dependency;
public SuperClass(DependencyClass dependency)
{
_dependency = dependency;
}
public abstract void DoSomething();
}
public class ChildClassCommon : SuperClass
{
private DependencyClass _dependency;
public ChildClassCommon(DependencyClass dependency)
{
_dependency = dependency;
}
public override void DoSomething()
{
}
}
public class ChildClassSpecial : SuperClass
{
private DependencyClass _dependency;
public ChildClassSpecial(DependencyClass dependency)
{
_dependency = dependency;
}
public override void DoSomething()
{
}
}
public class Main()
{
private IMyInterface _myClass;
public Main(IMyInterface myClass)
{
_myClass = myClass;
}
public void Selector(string recordType)
{
if(recordType == "Common")
{
// without DI, i would normally just do a new here to
// instantiate the concrete class, but with DI, I shouldnt be
// instantiating a new instance, but how do I select which
// concrete class to use?
_myClass = new ChildClassCommon(DependencyClass dependency);
}
else if (recordType == "Special")
{
_myClass = new ChildClassSpecial(DependencyClass dependency);
}
_myClass.DoSomething();
}
}
解决方案
您可以注册所有实现的类和工厂类。之后你可以解决工厂类。当您拥有工厂类时,您可以使用特定的生成规则生成所需的对象。
我Autofac
在这个例子中使用了 DI 工具
class Program
{
public class DependencyClass { }
public interface IMyInterface
{
void DoSomething();
}
public abstract class SuperClass : IMyInterface
{
protected DependencyClass _dependency;
public SuperClass(DependencyClass dependency)
{
_dependency = dependency;
}
abstract public void DoSomething();
}
public class ChildClassCommon : SuperClass
{
public ChildClassCommon(DependencyClass dependency) : base(dependency){}
public override void DoSomething(){}
}
public class ChildClassSpecial : SuperClass
{
public ChildClassSpecial(DependencyClass dependency) : base(dependency){}
public override void DoSomething(){}
}
public class MyInterfaceFactory
{
private IEnumerable<IMyInterface> _myInterfaces;
public MyInterfaceFactory(IEnumerable<IMyInterface> myInterfaces)
{
_myInterfaces = myInterfaces;
}
public IMyInterface Generate(string rule)
{
IMyInterface myObject;
if (rule == "a")
myObject = _myInterfaces.First(x => x is ChildClassCommon);
else
myObject = _myInterfaces.First(x => x is ChildClassSpecial);
return myObject;
}
}
// Injection run in this
static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterType<DependencyClass>().AsSelf();
builder.RegisterType<MyInterfaceFactory>().AsSelf();
var assembly = Assembly.GetExecutingAssembly();
builder
.RegisterAssemblyTypes(assembly)
.AssignableTo<IMyInterface>()
.AsImplementedInterfaces();
var container = builder.Build();
var factory = container.Resolve<MyInterfaceFactory>();
IMyInterface myInterface = factory.Generate("a");
Console.WriteLine(myInterface.GetType());
Console.ReadKey();
}
}
推荐阅读
- python-xarray - 如何在 Python 的 xarray.Dataset 中选择一些坐标?
- c - 我的自定义函数只工作一次,当我第二次使用该函数时,自定义函数中的相同布尔表达式未计算为真
- python - 调用多输入模型时。我收到错误:无法计算输出 KerasTensor
- vba - VBA / VSTO > Powerpoint > 隐藏辅助上下文菜单
- lit-element - 在 lit-element 中禁用样式隔离
- storybook - 故事书导航系统
- css - 谷歌字体显示默认字体
- c - 在c中通过cmd将可执行文件与参数分开不起作用
- reactjs - Redux 给出错误“错误:操作必须是普通对象。使用自定义中间件进行异步操作。”
- amazon-web-services - 无法使用 Pyspark 使用气流 emr 运算符从 EMR 集群连接到雪花