2

私は を持っておりObjectA、これには のプロパティがありObjectB、 には のプロパティがありますObjectC。これらはすべてSimple Injectorコンテナにあります。を作成するときObjectAに呼び出すInjectPropertiesと、 が読み込まれObjectBます。ただし、現時点ではObjectC、新しく作成された 内への参照はロードされませんObjectB。オブジェクトの「深いビルドアップ」と呼ばれるものは実行しません。

これを有効にする方法はありますか?

編集

私はクラスオブジェクトAを持っています:

public class ObjectA
{
     public ObjectB InstanceB { get; set; }
}

次のプロパティがありますObjectB

public class ObjectB
{
     public ObjectC InstanceC { get; set; }
}

すべては、コンテナーで標準の登録メソッドを使用して登録されています。を取得するにはObjectA、使用GetInstance<ObjectA>(),しますが、これは正常に戻ります。作成時にすべてのオブジェクトを構築するための初期化子も作成しました。

_container.RegisterInitializer<object>(i => _container.InjectProperties(i));

これは に注入ObjectBされますが、解決時に に注入されObjectAません。ObjectCObjectBObjectB

回避策はありますか? ありがとう。

4

1 に答える 1

3

私はあなたのコードとあなたの設定を使って少しテストを書きました(そして欠けているものを追加しましたObjectC):

public class ObjectA
{
    public ObjectB InstanceB { get; set; }
}

public class ObjectB
{
    public ObjectC InstanceC { get; set; }
}

public class ObjectC
{

}

テスト:

[TestMethod]
public void ImplicitPropertyInjectionTest()
{
    // Arrange
    var container = new Container();

    container.RegisterInitializer<object>(
        i => container.InjectProperties(i));

    // Act
    var a = container.GetInstance<ObjectA>();

    // Assert
    Assert.IsNotNull(a.InstanceB);
    Assert.IsNotNull(a.InstanceB.InstanceC);
}

テストは成功し、InstanceC正しく注入されます。構成に問題があるか、ClassC作成できない可能性があります。ClassCコンテナがそれを作成できない理由を見つけるために直接リクエストしてみてください:

container.GetInstance<ClassC>();

InstanceCこの行はおそらく失敗し、それが注入されない理由です。

これにより、次のことが直接わかります。

行ったように呼び出すRegisterInitializer<object>(instance => container.InjectProperties(instance))ことは、暗黙的なプロパティインジェクションを有効にする効果的な方法ですが、暗黙的なプロパティインジェクションの使用はできるだけ避ける必要があります。これは、(container.Verify()たとえばを使用して)検証できないコンテナ構成につながるためです。InstanceCスキップされたので、あなたはすでにこれに気づきました。代わりに、可能な限りコンストラクタインジェクションを使用する必要があります。ここで確認できる方法でコードを記述する方法の詳細については、こちらをご覧ください。

特定のシナリオでコンストラクターインジェクションを使用できない場合は、明示的なプロパティインジェクションを使用することをお勧めします。これは次のように実行されます。

container.RegisterInitializer<ClassA>(a =>
{
    a.InstanceB = container.GetInstance<ClassB>();
});

container.RegisterInitializer<ClassB>(b =>
{
    b.InstanceC = container.GetInstance<ClassC>();
});

InstanceBこれにより、プロパティとが明示的に挿入InstanceCされ、プロパティを挿入できない場合は構築に失敗します。

Simple Injectorを使用したプロパティインジェクションの詳細については、こちらをご覧ください

最後のメモ。暗黙的なプロパティインジェクションに関しては、すべてのコンテナがほぼ同じように動作することに注意してください。したがって、これはSimpleInjectorに固有のものではありません。この機能がそのコンテナでサポートされている場合、注入できないすべてのプロパティをスキップします。つまり、すべてのコンテナーはサイレントに失敗して続行しますが、これは通常、必要なことではありません。これは、デフォルトで暗黙的なプロパティインジェクションを有効にするコンテナを操作する場合は特に注意する必要があることを意味します。

于 2012-04-11T11:52:26.803 に答える