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