36

複数のコンストラクターを持つクラスがある場合、どのコンストラクターを使用するかをResolveに指示するにはどうすればよいですか?

次のクラスの例を考えてみましょう。

public class Foo
{
    public Foo() { }
    public Foo(IBar bar)
    {
        Bar = bar;
    }
    public Foo(string name, IBar bar)
    {
        Bar = bar;
        Name = name;
    }
    public IBar Bar { get; set; }        
    public string Name { get; set; }
}

Resolveを使用してFoo型のオブジェクトを作成する場合、Resolveはどのコンストラクターを使用するかをどのように認識しますか?そして、どうすれば正しいものを使用するように指示できますか?IBarが登録されたコンテナーがあるとしましょう-IBarを取得するコンストラクターを優先する必要があることを理解しますか?また、文字列も指定した場合、(string, IBar)コンストラクターを使用しますか?

Foo foo = unityContainer.Resolve<Foo>(); 

また、クラスにコンストラクターが1つしかない場合は、おそらく簡単になるという事実を無視してください...

4

2 に答える 2

63

ターゲットクラスに複数のコンストラクターが含まれている場合、UnityはInjectionConstructor属性が適用されているコンストラクターを使用します。複数のコンストラクターがあり、InjectionConstructor属性を持っているコンストラクターがない場合、Unityは最も多くのパラメーターを持つコンストラクターを使用します。そのようなコンストラクターが複数ある場合(同じ数のパラメーターを持つ「最長」のものが複数ある場合)、Unityは例外を発生させます。

リンクテキストから取得

于 2010-03-18T13:33:48.100 に答える
35

タイプを登録するときに、次のように使用するコンストラクターを指定できます。

container.RegisterType<Foo>(
    new InjectionConstructor(
        new ResolvedParameter<IBar>()));

上記のコードはメモリからのものですが、それが一般的な原則です。この場合、IBar型の単一のパラメーターを受け取るコンストラクターを選択しました。

また、クラスにコンストラクターが1つしかない場合は、おそらく簡単になるという事実を無視してください...

私はこれを無視することはできません。コンストラクターインジェクションに関して言えば、あいまいさはデザインの匂いです。あなたは基本的に言っています:私がこの依存関係を気にするかどうかは本当にわかりません。

確かに、Unityはそれを理解する可能性がありますが、APIを適切に設計するのではなく、特定のコンテナーの動作に依存することになります。他のコンテナーは異なる動作をする可能性があるため、Unityからより良いコンテナーに移行することを選択した場合、微妙なバグが発生する可能性があります。

DIに適しているが、コンテナーに依存しない方法でコードを記述する方がはるかに安全です。

于 2010-03-18T14:09:29.120 に答える