Unityは、結構お気に入りになりそうな感じなんだけど、あまりいじれてない。UnityContainerは、UnityContainerExtensionというものを使って簡単に拡張?出来るようになっている。
ということで、早速やってみた。
下準備として、IUnityContainerに登録するクラス群を定義する。とりあえず単純な足し算引き算を行うクラスを作った。
interface ICalc
{
int Execute(int lhs, int rhs);
}
class AddCalc : ICalc
{
public int Execute(int lhs, int rhs)
{
return lhs + rhs;
}
}
class MinusCalc : ICalc
{
public int Execute(int lhs, int rhs)
{
return lhs - rhs;
}
}
計算というものをICalcとしてインターフェースにしてみたよ。まぁ、サンプルなんでこんなもんで。次に、UnityContainerExtensionを継承したクラスを定義する。Initializeというメソッドをオーバーライドすることになるので、ここにコンテナの初期化処理を書く。今回は、AddUnityContainerExtensionとMinusUnityContainerExtensionを定義した。
上で作ったICalcやAddCalc,MinusCalcをUnityContainerに追加するためのクラスとして使える。
// 計算といえば足し算用でしょ拡張
class AddUnityContainerExtension : UnityContainerExtension
{
protected override void Initialize()
{
Container.RegisterType<ICalc, AddCalc>();
}
}
// 計算といえば引き算でしょ拡張
class MinusUnityContainerExtension : UnityContainerExtension
{
protected override void Initialize()
{
Container.RegisterType<ICalc, MinusCalc>();
}
}
UnityContainerExtensionにはContainerというプロパティが定義されているので、Containerプロパティを通じてUnityContainerにアクセスしている。ここで作ったUnityContainerExtensionは、AddNewExtensionメソッドを使ってUnityContainerに設定できるようになっている。
要は、各々のExtensionを追加することで、関連のあるものをUnityContainerに一括で登録できてしまうといったものみたいだ。早速作ったものを使ってみようと思う。
その前に、ICalcを使うクラスを定義してみた。
class CalcClient
{
[Dependency]
public ICalc Calc { get; set; }
public void Execute()
{
Console.WriteLine(Calc.Execute(10, 3));
}
}
計算して出力するだけ!シンプル。
長かったけど、やっとUnityContainerを使うよ!といってもコードは数行…
// コンテナを作って
var c = new UnityContainer();
// 足し算の計算用に拡張?して
c.AddNewExtension<AddUnityContainerExtension>();
// CalcClientをコンテナ経由で取得
c.RegisterType<CalcClient, CalcClient>();
var client = c.Resolve<CalcClient>();
client.Execute(); // -> 13
これを実行すると、10 + 3なので13と表示される。AddNewExtensionの部分をMinusUnityContainerExtensionに変更すると7 と表示される。
// コンテナを作って
var c = new UnityContainer();
// 引き算の計算用に拡張?して
c.AddNewExtension<MinusUnityContainerExtension>();
// CalcClientをコンテナ経由で取得
c.RegisterType<CalcClient, CalcClient>();
var client = c.Resolve<CalcClient>();
client.Execute(); // -> 7
今回のサンプルでは、一種類しかクラスを登録していなかったからありがたみは無いかもしれないけど、たとえばフレームワーク等で、関連のあるクラス群を一気に登録してしまおうというときにいいかもしれない。