找到你要的答案

Q:How can I create instance Dynamically with parameter constructor resolve using autofac DI

Q:我如何创建实例的动态参数的构造函数解决使用autofac迪

my code look like this

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();
}

my problem is

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

I register all dependency but I am getting No parameterless constructor defined for this object. Exception

我的代码看起来像这样

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

我登记的所有依赖但我没有为该对象定义无参数的构造函数。例外

answer1: 回答1:

While using Activator.CreateInstance(Type t) method you should make sure the type has parameterless consturctor available to type you are passing to its parametere otherwise it is gonna throw an exception that you got.

Why default consturctor is not there?

When you specify constructor with parameter in class default constructor is removed by compiler.

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

Use another overloaded method to pass constructor params there like below:

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

MSDN documentation for that method is here.

而使用活化剂。CreateInstance(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)
    {
    }
}

使用另一个重载方法通过构造函数的参数有如下:

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

该方法是在MSDN文档。

answer2: 回答2:

If you are using AutoFac you shouldn't need to use Activator to create instances.

Say what you are trying to do above lives in a class called DataService that has the following dependencies:

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

With the following AutoFac registrations:

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

Your DataService could then look like:

public class DataService
{
  private IEnumerable<IDataInstaller> _dataInstallers;

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

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

The DataService isn't concerned with having to know how to create all of the IDataInstaller instances, AutoFac can do that, it just needs a collection of them.

Note that even though you didn't actually register the IEnumerable<IDataInstaller> AutoFac provides some extra registrations implicitly when you register a type. See http://autofac.readthedocs.org/en/latest/resolve/relationships.html.

如果你使用的是autofac你不需要使用激活创建实例。

说什么你想做以上的一类称为数据业务具有依赖的生活:

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>();

你的数据可能看起来像:

public class DataService
{
  private IEnumerable<IDataInstaller> _dataInstallers;

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

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

该数据不关心如何创建所有的idatainstaller实例,autofac可以做到,只是需要一个收集他们。

请注意,即使你实际上没有登记的IEnumerable <;idatainstaller >;autofac提供一些额外的注册登记时会隐式类型。看到http://autofac.readthedocs.org/en/latest/resolve/relationships.html。

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