为什么解析集合也会创建1个元素?

时间:2015-06-24 16:25:28

标签: mono autofac

我在Mono上使用Autofac 3.5.2,当我尝试注册一个通用集合然后解决它时,我得到了正确的实例,其中已经添加了1个正确类型的元素。在代码中解释它:

class Fake {}

var builder = new ContainerBuilder();
builder.RegisterType<Fake>();
bilder.RegisterGeneric(typeof(List<>));

var scope = builder.Build();

var list = scope.Resolve<List<Fake>>();

Console.WriteLine(list.Count); // => prints 1!

这是预期的吗?为什么?我怎么能避免这种情况?

1 个答案:

答案 0 :(得分:1)

Autofac built-in support for collection,默认情况下会尝试在解析服务时使用构造函数包含最多可用参数。

  

Autofac会自动使用您的类的构造函数,其中包含可从容器中获取的最多参数   
  &GT; http://autofac.readthedocs.org/en/latest/register/registration.html#register-by-type

List<T>包含一个带IEnumerable<T>的构造函数。 当 Autofac 解析List<Fake>时,它会选择IEnumerable<T>的构造函数,然后解析IEnumerable<T>,这将解析{{1}的所有可用实例 1}}。

如果您注册了多个T Autofac 将在您解决时解决所有问题。例如:

Fake

您可以在注册var builder = new ContainerBuilder(); builder.RegisterType<Fake1>().As<IFake>(); builder.RegisterType<Fake2>().As<IFake>(); builder.RegisterGeneric(typeof(List<>)); var scope = builder.Build(); var list = scope.Resolve<List<IFake>>(); Console.WriteLine(list.Count); // => prints 2!

时指定要使用的构造函数
List<T>

或者您可以使用var builder = new ContainerBuilder(); builder.RegisterType<Fake1>().As<IFake>(); builder.RegisterType<Fake2>().As<IFake>(); builder.RegisterGeneric(typeof(List<>)).UsingConstructor(Type.EmptyTypes); var scope = builder.Build(); var list = scope.Resolve<List<IFake>>(); Console.WriteLine(list.Count); // => prints 0! 方法中的ContainerBuildOptions.ExcludeDefaultModules参数忽略默认行为

Build

我不建议删除默认行为,除非你真的知道你做了什么。