根据触发解析的父树解析参数?

时间:2015-05-12 17:36:25

标签: 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实例.B传递给C1的实例应该得到为C1创建的A的相同实例。 C2和他的参数应该有一个不同的A实例。如何在Autofac中配置这个场景?看起来像Owned实例生命周期功能应该处理这个,但是发布的示例只有一层深,而不是两个。

我的实际情况要复杂得多。我有十几个IB的继承者和六个C defs,它们采用了IB继承者的各种组合。我想避免使用命名实例,因为这会大大增加我的引导程序并使其难以维护。

次要问题:DryIoc是否支持此功能?我可以谈到切换。

2 个答案:

答案 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需要在图中标识/查找范围。例如,如果serviceKeyC1实现相同的接口C2,则不需要服务密钥。您只需说IC,图表中的每个Reuse.InResolutionScopeOf<IC>()对象都只有一个IA

答案 1 :(得分:2)

您正在寻找一种名为“每个图形实例”的生命周期范围。 autofac本身不支持它。如果您没有使用autofac,可以使用Castle Windsor as explained in this related/duplicate question

如果您正在寻找使用autofac的解决方案,可以使用InstancePerMatchingLifetimeScopeInstancePerLifetimeScope来实施。

以下是配置容器的方法

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