それを分解しましょう:
_container.RegisterType<Music>(new InjectionConstructor(
new Album("Non-singleton", "Non-singleton")));
これにより、名前のない型 (null またはデフォルト) がコンテナーに登録され、型Music
を受け入れるコンストラクターを使用するように Unity に指示されますAlbum
。new Album("Non-singleton", "Non-singleton")
また、によって作成されたインスタンスを値として常にMusic(Album album)
コンストラクターに渡します。したがって、すべてMusic
のインスタンスに同じアルバムが注入されます。
_container.RegisterType<Music>(new ContainerControlledLifetimeManager());
Music
これは、名前のないタイプ (null またはデフォルト)に基づいて登録を実行します。指定された InjectionMembers がないため、既存の登録への唯一の変更は、ライフタイム マネージャーを追加することです。BuildKey (Type: Music、Name: null) が両方の RegisterType 呼び出しで同じであるため、既存の登録が更新されます。
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 であるため、単一のインスタンスが返されます。
Name 属性を指定せずに、同じコンテナー内の 2 つの登録済みオブジェクトのシングルトン タイプのみを解決する方法はありますか?
タイプはタイプと名前で登録されるため、同じタイプを複数登録する唯一の方法は、名前を使用することです。
// Named registration
unityContainer.RegisterType<Music>("NonSingleton Name",
new InjectionConstructor(new Album("Non-singleton", "Non-singleton")));
// Default (null) registration
unityContainer.RegisterType<Music>(new ContainerControlledLifetimeManager());
最初の登録をオーバーライドしたい場合は、新しい InjectionConstructor を指定することでそれを行うことができます。これにより、ビルド プランがクリアされ、コンストラクターの選択ポリシーが設定されます。
unityContainer.RegisterType<Music>(new InjectionConstructor(
new Album("Non-singleton", "Non-singleton")));
unityContainer.RegisterType<Music>(new ContainerControlledLifetimeManager(),
new InjectionConstructor(new Album("singleton", "singleton")));
補足として、依存関係 (この場合はアルバム) が本当に定数値でない限り、通常はレジスタ型呼び出し内にハードコーディングしません。それでも、定数インスタンスをシングルトンとして登録し、コンテナーに解決させたい場合があります。
興味深い質問は、Unity がデフォルトのコンストラクター選択ポリシーを使用するように、最初の RegisterType 呼び出しの後にコンストラクター選択ポリシーをリセットする方法です。これは、コンストラクターの選択ポリシーをクリアするカスタム 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));
}
}