【Unity】RegisterInstanceとRegisterTypeの違い。
- 2009.03.01 Sunday
- 02:51
Source and Project
Unity Application Block 1.2のRegisterInstanceメソッドとRegisterTypeメソッドの違いに関して取り上げます。
RegisterInstanceメソッド
RegisterInstanceメソッドはDIコンテナにTypeとNameをキー情報として、Typeにキャスト可能なインスタンスを登録することができます。LifetimeManagerを指定しない場合は、ContainerControlledLifetimeManagerがデフォルト値として設定されます。
RegisterInstanceメソッドで登録した場合に注意しなければならないのは、DIコンテナからインスタンスを破棄した場合です。
Typeがインターフェイスの場合
RegisterInstanceメソッドは外部で生成したインスタンスを登録しているため、基本的にはインスタンスの生成方法をコンテナは知りません。何らかの方法でコンストラクタする方法をコンテナに知らせて置かないと、一度、インスタンスを破棄した後にインスタンスをコンテナから取得しようとすると例外(Microsoft.Practices.Unity.ResolutionFailedException)が発生します。LifetimeManagerがコンテナ単位でシングルトンになるようにContainerControlledLifetimeManagerが設定されているのは、上記のような理由があるからと推測されます。
Typeがクラスの場合
指定されたクラスにカレントのコンストラクタ情報を指定している場合のみコンテナの格納されているインスタンスを破棄しても新しいインスタンスが生成可能です。ただし、そのような使用ケースは本来RegisterTypeメソッドで行うべきです。
RegisterTypeメソッド
RegisterTypeメソッドは以前にも紹介しましたが、RegisterTypeメソッドはコンテナにTypeおよびNameをキー情報として、クラス(静的な情報)を関連づけます。どのコンストラクタをカレントとするか指定し、必要な引数をインジェクションする設定をしていれば、ResolveまたはResolveAllなどを実行した際に、指定したクラスからインスタンスが作成できます。
RegisterTypeとResigsterInstanceの違いは、静的な情報を登録するか動的な情報を登録するかの違いです。また、別の言い方をすれば、コンテナ内でインスタンスを作成する(実際には作成するための情報)か、外部で作成したインスタンスをコンテナに渡すかの違いです。ResigsterTypeはクラス同士の関連とオブジェクト同士の関連に差異がないようなケースで有効です。この場合、静的な情報がそのまま動的な情報になるからです。つまりコンパイル時に宣言した内容がそのままオブジェクトとして動作可能な状況です。ResigsterInstanceの場合は、DIコンテナの機能ではサポートできないような複雑なコンストラクタや別のインスタンス作成機構がある場合に有効です。また、ユーザのアクションによって、コンテナで管理する必要が発生するケースにも対応できます。ということで、状況に応じて、
RegisterTypeとResigsterInstanceは使い分けることができます。また、キー情報となるTypeとNameは共有されているので、後から書き換える事もできます。
今回のサンプルコードはRegisterInstanceメソッドの簡単なサンプルコードです。
class Program
{
static void Main(string[] args)
{
IUnityContainer container = new UnityContainer();
var lifetimeManager = new ContainerControlledLifetimeManager();
container.RegisterInstance<IA>("A", new AImpl(), lifetimeManager);
var a = container.Resolve<IA>("A");
a.Execute();
lifetimeManager.Dispose();
try
{
var a2 = container.Resolve<IA>("A");
}
catch (ResolutionFailedException e)
{
Console.WriteLine(e.Message);
}
}
}
internal interface IA
{
void Execute();
}
class AImpl : IA
{
public AImpl()
{
Console.WriteLine("AImple()");
}
public void Execute()
{
Console.WriteLine("AImpl.Execute()");
}
}
実行すると
まとめます。
1.RegisterTypeメソッドで静的な情報をType(OutputのType)とNameをキーにして
登録することができる。
2.RegisterInstanceメソッドで動的な情報をType(OutputのType)とNameをキーにして
登録することができる。
以上!
Source and Project