2

私はObjectAを持っています。ObjectBのプロパティを持っています。これはObjectCのプロパティを持ち、すべてSimple Injectorコンテナに入っています。 ObjectAを作成すると、InjectPropertiesが呼び出され、ObjectBが読み込まれます。ただし、この時点では、新しく作成されたObjectB内にはObjectCへの参照がロードされません。私はオブジェクトの「深いビルドアップ」と呼ぶものを実行しません。SimpleInjectorは暗黙プロパティインジェクションを使用してプロパティを注入しません

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

EDIT

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

ObjectBの性質を持っている
public class ObjectA 
{ 
    public ObjectB InstanceB { get; set; } 
} 

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

すべてが上の標準registerメソッドを使用して登録されていますコンテナ。 ObjectAを取得するには、私はGetInstance<ObjectA>(),を使用し、これは罰金戻ってくる、私はまた、作成時にすべてのオブジェクトを構築するための初期化子を建て:

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

これはObjectAObjectBを注入が、その後で、ObjectBObjectCを注入していません解決する時間はObjectBです。

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

+0

シンプルインジェクタシステムではツリー全体を構築する必要があります。コンテナ登録を含むサンプルコードを投稿できますか? 構築後にプロパティを明示的に注入するのではなく、コンストラクタ注入を使用することを検討してください。このパターンを変更できない場合は、Unityのような別のIoCコンテナを考慮する必要があります。これは間違いなくポスト建設深いビルドアップをサポートします –

+0

これらのクラスのコードと登録を表示してください。私は、Unity(特にUnity)に切り替えることを除いて、ほとんどのRobertが言ったことに同意します。 – Steven

答えて

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を作成することはできません。

container.GetInstance<ClassC>(); 

この行はおそらく失敗し、それがInstanceCが注入されていないことを理由です:コンテナはそれを作成できない理由を確認するために、直接ClassCを要求してみてください。

これは直接次で私をもたらします:

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

それは特定のシナリオでコンストラクタ・インジェクションを使用することは不可能である場合は、次のように行われている明示的なプロパティインジェクションを使用して好む:

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

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

これは、明示的な特性InstanceBInstanceCを注入し、そして時にプロパティ建設を失敗します。注入できません。

シンプルインジェクターでプロパティインジェクションを行う方法の詳細はhereです。

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

関連する問題