6

Unityでもう少し理解するために遊んできました。同じタイプを2回登録して1つをシングルトンにすると、Resolveにはどのようにしてシングルトンだけが返されますか?私はこれがユニークなNameを使用して達成できることを理解しますが、これがなくてもいいのかと思っています。例えば同じタイプを2回登録してシングルトンのみを解決するための統一動作

_container.RegisterType<Music>(new InjectionConstructor(new Album("Non-singleton", "Non-singleton"))); 
_container.RegisterType<Music>(new ContainerControlledLifetimeManager()); 

var music = Factory.Resolve<Music>(); 
を呼び出すと、 '非シングルトン' オブジェクトを返します。最初は登録オーダーに基づいていると思っていましたが、その周りを切り替えると「Non-singleton」インスタンスが表示されます。

これには理由がありますか?同じコンテナ内に登録された2つのオブジェクトのシングルトンタイプのみをResolveにする方法はありますか?Name属性を指定していますか?

答えて

21

のは、それを打破してみましょう:

_container.RegisterType<Music>(new InjectionConstructor(
    new Album("Non-singleton", "Non-singleton"))); 

を。これは、コンテナ名前のないタイプMusic(nullまたはデフォルト)に登録され、タイプAlbumを受け取るコンストラクタを使用するようにUnityに伝えます。また、常にnew Album("Non-singleton", "Non-singleton")によって作成されたインスタンスを値としてMusic(Album album)コンストラクタに渡すようにします。したがって、Musicのインスタンスには、同じアルバムが挿入されます。

_container.RegisterType<Music>(new ContainerControlledLifetimeManager()); 

これは、名前のない(ヌルまたはデフォルト)とタイプMusicに基づいて登録を行います。 InjectionMembersが指定されていないため、既存の登録を変更するだけで、ライフタイムマネージャが追加されます。両方のRegisterType呼び出しでBuildKey(Type:Music、Name:null)が同じであるため、既存の登録が更新されます。

unityContainer.RegisterType<Music>(new InjectionConstructor(new Album("Non-singleton", "Non-singleton"))); 

unityContainer.RegisterType<Music>(new ContainerControlledLifetimeManager()); 

var music = unityContainer.Resolve<Music>(); 
var music2 = unityContainer.Resolve<Music>(); 

bool areEqual = ReferenceEquals(music, music2); 

上記のareEqualはtrueであるため、1つのインスタンスが返されます。

ワット/ Name属性を指定してから、同じコンテナ内の2つ登録されたオブジェクトのための唯一のシングルトンの種類を解決する方法はありますか?今

あなたはあなたができる最初の登録を無効にしたい場合:同じタイプの名前を使用することであるための唯一の方法は、複数の登録を持つよう

タイプタイプと名前で登録されていますそれは新しいInjectionConstructorを指定することによってそれです。これにより、ビルドプランがクリアされ、コンストラクタ選択ポリシーが設定されます。サイドノートとして

unityContainer.RegisterType<Music>(new InjectionConstructor(
    new Album("Non-singleton", "Non-singleton"))); 

unityContainer.RegisterType<Music>(new ContainerControlledLifetimeManager(), 
    new InjectionConstructor(new Album("singleton", "singleton"))); 

、あなたは通常はハードコードの依存(この場合はアルバム)レジスタタイプのコールの内側だろう、それは本当に、一定値でない限り。その場合でも、定数インスタンスをシングルトンとして登録して、コンテナでそれを解決させることができます。

興味深いのは、最初のRegisterType呼び出しの後にコンストラクタ選択ポリシーをリセットして、Unityがデフォルトのコンストラクタ選択ポリシーを使用する方法です。コンストラクタの選択ポリシーをクリアするカスタムのInjectionMemberでこれを行うことができます:

unityContainer.RegisterType<Music>(new InjectionConstructor(
    new Album("Non-singleton", "Non-singleton"))); 

unityContainer.RegisterType<Music>(new ContainerControlledLifetimeManager(), 
    new ClearInjectionConstructor()); 

public class ClearInjectionConstructor : InjectionMember 
{ 
    public override void AddPolicies(Type serviceType, 
     Type implementationType, 
     string name, 
     Microsoft.Practices.ObjectBuilder2.IPolicyList policies) 
    { 
     policies.Clear<IConstructorSelectorPolicy>(
      new NamedTypeBuildKey(implementationType, name)); 
    } 
} 
関連する問題