17

问题:

假设类:

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:

AwesomeMethodB)在之前 使用里面的解析器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具有依赖关系?

4

6 回答 6

11

看看组合根模式。

你是对的,拉起依赖解决方案只会将问题转移到另一个地方。但是,如果您继续在对象图中向上移动它,您将到达应用程序的入口点。在那里你将组成你的对象图。

将其与Service Locator 反模式(在您的案例中在客户端类中使用 DependencyResolver)进行比较,您会发现 Composition Root 是一个出色的解决方案。

于 2012-05-29T14:13:04.390 回答
1

首先,除了构造函数注入之外,您还可以使用属性注入方法注入。但是构造函数注入是最常见也是最快的方法,所以我建议坚持下去。

你需要做的第二件事是MyAwesomeClass在 Autofac 容器中注册你的依赖项,他们的主页上有一些很好的例子。

最后一件事——你不应该直接创建实例MyAwesomeClass——使用 Autofac 代替。这是一个更新的示例:

public void AwesomeMethod()
{
    //...
    // AwesomeStuff
    //...

    var GetErDone = DependencyResolver.Current.GetService<MyAwesomeClass>();
}
于 2012-05-29T13:42:04.310 回答
1

您可以使用反射创建“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;
    }
于 2020-01-02T16:11:44.477 回答
0

如果你想通过 Autofac 自动解析实例,你只能从这里选择

  • 注入你的类的构造函数
  • 通过使用注入属性

    var builder = new ContainerBuilder();

    builder.RegisterType<Foo>().PropertiesAutowired();

  • 使用全局访问权限DependencyResolver.Current.GetService<IFoo>();

于 2012-05-29T12:47:40.370 回答
0

在包含MyAwesomeMethodtakeMyAwesomeClass作为构造函数依赖的类中。Autofac 将负责实例化。

于 2012-05-29T13:25:23.060 回答
0

我知道这个问题很老,但我在描述类动态实例化的 autofac 文档上找到了一个非常有用的链接。

Autofac 动态实例化

也许它可能对某人有帮助。

于 2019-09-16T09:42:05.183 回答