如何使用autofac DI解析参数构造函数动态创建实例

时间:2015-02-19 05:57:46

标签: c# asp.net-mvc dependency-injection autofac dynamic-programming

我的代码看起来像这样

private void installData()
{
    var dataInstallServices = new List<IDataInstallationService>(); 
    var dataInstallServiceTypes=_typeFinder.FindClassesOfType<IDataInstallationService>();

    foreach (var dataInstallServiceType in dataInstallServiceTypes)
        dataInstallServices.Add((IDataInstallationService)Activator.CreateInstance(dataInstallServiceType));

    foreach (var installServie in dataInstallServices)
        installServie.InstallData();
}

我的问题是

dataInstallServices.Add((IDataInstallationService)Activator.CreateInstance(dataInstallServiceType,"parameters resolve using autofac"))

我注册了所有依赖项,但我得到没有为此对象定义无参数构造函数。异常

2 个答案:

答案 0 :(得分:0)

如果您使用的是AutoFac,则不需要使用Activator来创建实例。

说出你在上面尝试做的事情,生活在一个名为DataService的类中,该类具有以下依赖关系:

public class DataInstallerA : IDataInstaller {
  public DataInstallerA(SubDependencyA a){}
}
public class DataInstallerB : IDataInstaller  {
  public DataInstallerA(SubDependencyB b){}
}

使用以下AutoFac注册:

builder.RegisterType<SubDependencyA>();
builder.RegisterType<SubDependencyB>();
builder.RegisterType<DataInstallerA>().As<IDataInstaller>();
builder.RegisterType<DataInstallerA>().As<IDataInstaller>();
builder.RegisterType<DataService>();

您的DataService可能如下所示:

public class DataService
{
  private IEnumerable<IDataInstaller> _dataInstallers;

  public DataService(IEnumerable<IDataInstaller> dataInstallers) {
    _dataInstallers = dataInstallers;
  }

  public void Install() {
    foreach (var installer in _dataInstallers)
      installer.InstallData();
  }
}

DataService并不关心必须知道如何创建所有IDataInstaller个实例,AutoFac可以做到这一点,它只需要它们的集合。

请注意,即使您没有实际注册IEnumerable<IDataInstaller>,当您注册类型时,AutoFac会隐式提供一些额外的注册。请参阅http://autofac.readthedocs.org/en/latest/resolve/relationships.html

答案 1 :(得分:-1)

在使用Activator.CreateInstance(Type t)方法的同时,你应该确保该类型具有无参数的consturctor可用于输入你的参数,否则它会抛出你得到的异常。

为什么默认的consturctor不存在?

在类中使用参数指定构造函数时,编译器会删除构造函数。

using System;

public class Program
{
    public static void Main()
    {
        Test t = new Test() //will give you compile time error.
        Test t1 = new Test(""); //should work fine.

    }
}

public class Test
{
    public Test(string a)
    {
    }
}

使用另一个重载方法在下面传递构造函数params:

Activator.CreateInstance(typeof(T), param1, param2);

该方法的MSDN文档为here