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

本文关键字:动态 创建 实例 构造函数 参数 autofac 何使用 DI | 更新日期: 2024-06-14 05:42:26

我的代码看起来像这个

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"))

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

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

如果使用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.

在使用Activator.CreateInstance(Type t)方法时,您应该确保该类型具有可用于传递给其参数的类型的无参数构造函数,否则它将抛出您得到的异常。

为什么不存在默认构造函数

当您在类中使用参数指定构造函数时,编译器将删除默认构造函数。

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)
    {
    }
}

使用另一个重载方法在那里传递构造函数参数,如下所示:

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

该方法的MSDN文档在这里。