使用Autofac创建具有依赖项的类的实例

时间:2012-05-29 12:38:55

标签: c# asp.net-mvc dependency-injection inversion-of-control autofac

问题:

假设上课:

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

6 个答案:

答案 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 injectionmethod injection。然而,构造函数注入是最常见的,也是最快的方法,因此我建议坚持使用它。

您需要做的第二件事是在Autofac容器中注册MyAwesomeClass及其依赖项,在主页上有一些不错的examples

最后一件事 - 你不应该直接创建MyAwesomeClass的实例 - 而是使用Autofac。这是一个更新的例子:

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

    var GetErDone = DependencyResolver.Current.GetService<MyAwesomeClass>();
}

答案 4 :(得分:0)

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

Autofac Dynamic Instantiation

也许对某人有帮助。

答案 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;
    }