C# 根据触发解析的父树解析参数?
我有类似的代码:C# 根据触发解析的父树解析参数?,c#,dependency-injection,autofac,dryioc,C#,Dependency Injection,Autofac,Dryioc,我有类似的代码: 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的实例。传递给C1的B的实例应该得到为C1创建的A的
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的实例。传递给C1的B的实例应该得到为C1创建的A的相同实例。C2和他的参数应该有一个不同的a实例。我如何在Autofac中配置此场景?看起来拥有的实例生命周期功能应该处理此问题,但发布的示例只有一层,而不是两层
我的真实情况要复杂得多。我有十几个IB继承器和半打C DEF,它们采用IB继承器的各种组合。我希望避免使用命名实例,因为这会大大增加我的引导程序的容量,并使其难以维护
第二个问题:国际奥委会是否支持这一点?我可能会被说服进行切换。您正在寻找一种称为“每图实例”的生命周期范围。autofac本机不支持它。如果您没有被autofac困扰,可以使用 如果您正在寻找使用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();
}
在(我的)中,可通过以下方式直接实现:
container.Register(设置:setup.With(openResolutionScope:true),serviceKey:Some.Blah);
Register(setup:setup.With(openResolutionScope:true),serviceKey:Some.Blah);
Register(重用:reuse.InResolutionScopeOf(serviceKey:Some.Blah));
就这样
openResolutionScope:true
在对象图中创建范围。serviceKey
需要在图中标识/查找范围。例如,如果C1
和C2
将实现相同的接口IC
,则不需要维修密钥。您只需在ResolutionScopeof()中说Reuse.in
,图形中的每个IC
对象都将有一个IA
。感谢您出色的代码演示。我必须进一步考虑这一点,因为我实际上没有对任何C对象调用Resolve
。它们都是一条链的下游。我只从容器中解析了几个高级对象,其余的(600ish)都是通过工厂和构造必要的构造函数依赖项来填充的。@Brannon我知道如果你不为这些对象调用resolve
,那会很痛苦。一种方法是将这些代码隐藏在factory类中。因此,您可以调用factory.CreateC1()
factory将封装一个容器,并为您创建LifetimeScope和调用resolve。Autofac直接支持InstancePer graph”和InstancePerOwned
lifetime(与DryIoc的做法非常类似):c.RegisterType().InstancePerOwned();//A在C中被重用
@dadhi它与每个图的实例相同吗?它迫使我们在我们的实体中使用Owned
类型,对吗?这意味着我们与IOC容器紧密耦合——这是一件坏事。如果我错了,请纠正我。这种方法有优点也有缺点,但那是另一件事:优点:使用Owned轻松为您提供IDispose。缺点:是的,您需要引用容器来使用自有包装器。DryIoc在没有包装器的情况下支持这一点,但要能够进行处理,您仍然需要解决方案处理。如果您是DryIoc的作者,您需要公开它。否则这里的人会认为这是垃圾邮件之类的。谢谢
[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;
}
}
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));