我的代码类似于:
class A: IA { ... }
class B: IB {
public B(IA a, ...) { ... }
...
}
class C1 {
public C1(IA a, IB b, ...) { ... }
}
class C2 {
public C2(IA a, IB b, ...) { ... }
}
我想要的只是A的两个实例 - 一个与C1一起使用,一个与C2一起使用。我想要两个B实例.B传递给C1的实例应该得到为C1创建的A的相同实例。 C2和他的参数应该有一个不同的A实例。如何在Autofac中配置这个场景?看起来像Owned实例生命周期功能应该处理这个,但是发布的示例只有一层深,而不是两个。
我的实际情况要复杂得多。我有十几个IB的继承者和六个C defs,它们采用了IB继承者的各种组合。我想避免使用命名实例,因为这会大大增加我的引导程序并使其难以维护。
次要问题:DryIoc是否支持此功能?我可以谈到切换。
答案 0 :(得分:4)
在DryIoc(我的)中,可以使用Reuse.InResolutionScopeOf直接实现:
onResume() {}
那就是它。 container.Register<C1>(setup: Setup.With(openResolutionScope: true), serviceKey: Some.Blah);
container.Register<C2>(setup: Setup.With(openResolutionScope: true), serviceKey: Some.Blah);
container.Register<IA, A>(reuse: Reuse.InResolutionScopeOf(serviceKey: Some.Blah));
在对象图中创建范围。openResolutionScope: true
需要在图中标识/查找范围。例如,如果serviceKey
和C1
实现相同的接口C2
,则不需要服务密钥。您只需说IC
,图表中的每个Reuse.InResolutionScopeOf<IC>()
对象都只有一个IA
。
答案 1 :(得分:2)
您正在寻找一种名为“每个图形实例”的生命周期范围。 autofac本身不支持它。如果您没有使用autofac,可以使用Castle Windsor as explained in this related/duplicate question。
如果您正在寻找使用autofac的解决方案,可以使用InstancePerMatchingLifetimeScope
或InstancePerLifetimeScope
来实施。
以下是配置容器的方法
private IContainer Build()
{
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<A>().As<IA>().InstancePerMatchingLifetimeScope("SomeTag");
builder.RegisterType<B>().As<IB>().InstancePerMatchingLifetimeScope("SomeTag");
builder.RegisterType<C1>();
return builder.Build();
}
以下是您使用它的方式
[Test]
public void PerGraphLifeStyle()
{
var container = Build();
C1 c1;
C1 c2;
using (var scope = container.BeginLifetimeScope("SomeTag"))
{
c1 = scope.Resolve<C1>();
Assert.AreSame(c1.A, c1.B.A);
}
using (var scope = container.BeginLifetimeScope("SomeTag"))
{
c2 = scope.Resolve<C1>();
Assert.AreSame(c1.A, c1.B.A);
}
Assert.AreNotSame(c1.A, c2.A);
}
我为测试而创建的虚拟课程在
之下internal interface IA
{
}
class A : IA
{
}
internal interface IB
{
IA A { get; set; }
}
class B : IB
{
public B(IA a)
{
A = a;
}
public IA A { get; set; }
}
class C1
{
public IA A { get; set; }
public IB B { get; set; }
public C1(IA a, IB b)
{
A = a;
B = b;
}
}