问题:
假设上课:
public class MyAwesomeClass
{
private IDependCls _dependCls;
public MyAwesomeClass(IDependCls dependCls)
{
_dependCls = dependCls;
}
}
在其他地方我需要获得该类的实例,如下所示:
public class SomewhereElse
{
public void AwesomeMethod()
{
//...
// AwesomeStuff
//...
var GetErDone = new MyAwesomeClass(); // PROBLEM! No constructor with 0 arguements
}
}
问题是,我
建议的解决方案1:
A)必须制作一个额外的构造函数来解决依赖关系吗?例如:
public MyAwesomeClass() // new constructor
{
_dependCls = DependencyResolver.Current.GetService<IDependCls>();
}
public class SomewhereElse
{
public void AwesomeMethod()
{
var GetErDone = new MyAwesomeClass(); // IT WORKS!!
}
}
提议的解决方案2:
B)在AwesomeMethod
var GetErDone
内的解析器
public class SomewhereElse
{
public void AwesomeMethod()
{
var depCls = _dependCls = DependencyResolver.Current.GetService<IDependCls>();
var GetErDone = new MyAwesomeClass(depCls); // IT WORKS!!
}
}
Autofac解决方案?
C)其他一些Autofac方式?
寻找最佳实践,以及尽可能好的Autofac解决方案。我认为第一种方式是最差的,因为可选的依赖可能会导致很多混乱。
要点:
如果new MyAwesomeClass()
有依赖关系,我如何获得MyAwesomeClass
答案 0 :(得分:9)
查看Composition Root模式。
你是对的,提升依赖性解决方案只会将问题转移到另一个地方。但是,如果继续在对象图中向上移动,则会到达应用程序的入口点。在那里,您将编写对象图。
将其与Service Locator anti-pattern进行比较(在您的案例中使用客户端类中的DependencyResolver),您将看到Composition Root是一个出色的解决方案。
答案 1 :(得分:0)
如果您想通过Autofac自动解析实例,则只能从此选择
使用
注入属性 var builder = new ContainerBuilder();
builder.RegisterType<Foo>().PropertiesAutowired();
使用DependencyResolver.Current.GetService<IFoo>();
答案 2 :(得分:0)
在包含MyAwesomeMethod
的类中,将MyAwesomeClass
作为构造函数依赖项。 Autofac将负责实例化。
答案 3 :(得分:0)
首先,除了构造函数注入之外,您还可以使用property injection和method injection。然而,构造函数注入是最常见的,也是最快的方法,因此我建议坚持使用它。
您需要做的第二件事是在Autofac容器中注册MyAwesomeClass
及其依赖项,在主页上有一些不错的examples。
最后一件事 - 你不应该直接创建MyAwesomeClass
的实例 - 而是使用Autofac。这是一个更新的例子:
public void AwesomeMethod()
{
//...
// AwesomeStuff
//...
var GetErDone = DependencyResolver.Current.GetService<MyAwesomeClass>();
}
答案 4 :(得分:0)
答案 5 :(得分:0)
您可以使用反射创建'MyAwesomeClass'的新实例,并使用Autofac解析构造函数参数。
public static T Instance<T>() where T : class
{
Type instanceType = typeof(T);
ConstructorInfo constructorInfo = instanceType.GetConstructors()[0];
ParameterInfo[] constructorParamsInfo = constructorInfo.GetParameters();
object[] constructorParams = new object[constructorParamsInfo.Length];
for (int i = 0; i < constructorParamsInfo.Length; i++)
{
var parameterInfo = constructorParamsInfo[i];
var type = parameterInfo.ParameterType;
constructorParams[i] = Container.Resolve(type);
}
object instance = Activator.CreateInstance(instanceType, constructorParams);
return (T)instance;
}