Autofac可以为每个接口执行不同的实例范围设计吗?

时间:2014-05-23 12:51:47

标签: c# autofac lifetime-scoping

假设我的引导代码中有这一行:

builder.RegisterType<MyType>().As<IMyType>().As<IMyTypeBase>().ExternallyOwned();

我希望每当我使用container.Resolve<IMyType>()时,我都会得到MyType的新实例。但是,如果我使用container.Resolve<IEnumerable<IMyTypeBase>>(),我就不想要新实例。我想要所有已经创建的实例。这可以用Autofac吗?

1 个答案:

答案 0 :(得分:1)

您的要求似乎有冲突,您应该重新考虑您的策略。您想要的行为可能会导致非常令人惊讶的结果,并确定解析哪些类型的顺序,甚至是构造函数参数的排序顺序。

例如,请查看以下示例:

var instance1 = container.Resolve<IMyType>();
var instance2 = container.Resolve<IEnumerable<IMyTypeBase>>().First();

Assert.AreSame(instance1, instance2);

这里我们首先解析IMyType并稍后解析IMyTypeBase个实例的集合,并期望集合返回相同的实例。但是,如果我们扭转局面呢?

var instance2 = container.Resolve<IEnumerable<IMyTypeBase>>().First();
var instance1 = container.Resolve<IMyType>();

你还期望两个实例都一样吗?调用Resolve<IEnumerable<IMyTypeBase>>()时,还没有MyType实例,因此将创建它。但您的要求是在解析IMyType时始终创建一个新实例,因此在这种情况下将创建两个实例。

更糟糕的是,请看一下以下两个构造函数:

public SomeService(IMyType type, IEnumerable<IMyTypeBase> types) { ... }

public OtherService(IEnumerable<IMyTypeBase> types, IMyType type) { ... }

OtherService首先定义IEnumerable<IMyTypeBase>参数的简单事实将导致创建两个MyType个实例。您可能会在这种特殊情况下看到这一点,但由于对象图可能变得非常深,因此几乎不可能猜出要创建MyType的实例数。