2

次のようなコードがあります。

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 の 2 つのインスタンスだけです。1 つは C1 に、もう 1 つは C2 に使用します。B の 2 つのインスタンスが必要です。C1 に渡される B のインスタンスは、C1 用に作成された A の同じインスタンスを取得する必要があります。C2 と彼のパラメーターには、A の異なるインスタンスが必要です。Autofac でこのシナリオを構成するにはどうすればよいですか? 所有インスタンスの有効期間機能がこれを処理するはずだったように見えましたが、投稿された例は 2 層ではなく 1 層のみでした。

私の実際の状況はもっと複雑です。私は IB の継承者を 12 個と、IB 継承者のさまざまな組み合わせを取る 6 個の C 定義を持っています。名前付きインスタンスの使用は避けたかったのです。これは、ブートストラップが大幅に肥大化し、保守が困難になるためです。

二次的な質問: DryIoc はこれをサポートしていますか? 私は切り替えに話しかけられる可能性があります。

4

2 に答える 2

4

DryIoc (これは私のものです) では、 Reuse.InResolutionScopeOf を使用して直接実現できます

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グラフ内の範囲を特定/見つけるために必要です。たとえば、C1C2が同じインターフェイスを実装するIC場合、サービス キーは必要ありません。あなたが言うだけで、グラフ内の各オブジェクトに対してReuse.InResolutionScopeOf<IC>()1つになります。IAIC

于 2015-05-15T13:35:49.147 に答える
2

「グラフごとのインスタンス」の有効期間スコープと呼ばれるものを探しています。autofac ではネイティブにサポートされていません。autofac にこだわっていない場合は、この関連/重複した質問で説明されているように、Castle Windsor を使用できます。

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;
    }
}
于 2015-05-12T21:57:34.173 に答える