Enterprise Libraryの核の部分で使われているという噂のUnityを少し触ってみた。Unityとは、DIコンテナらしい。
とりあえずは、ハローワールドからしてみよう。
まず、コンソールアプリケーションを作成して、二つのアセンブリを参照に追加する。
- Microsoft.Practices.ObjectBuilder2
- Microsoft.Practices.Unity
そして、Unityに登録するためのクラスを作る。とりあえずありがちな挨拶を題材に適当なクラスを作成した。
namespace EntLibTest
{
interface IGreeter
{
string Greet();
}
class JapaneseGreeter : IGreeter
{
public string Greet()
{
return "こんにちは";
}
}
class EnglishGreeter : IGreeter
{
public string Greet()
{
return "Hello";
}
}
}
Unityの使い方は、UnityContainerのインスタンスを作成してRegisterXXXというメソッドで、型を登録してResolveXXXXというメソッドでインスタンスを取得する。
JapaneseGreeterとEnglishGreeterを登録して、取得して使う場合は下のようなコードになる。
using System;
using Microsoft.Practices.Unity;
namespace EntLibTest
{
class Program
{
static void Main(string[] args)
{
var c = new UnityContainer();
// JapaneseGreeterとEnglishGreeterを登録する
// 同じ型で複数登録しない場合は、引数の名前はいらない
// c.RegisterType<IGreeter, JapaneseGreeter>()でOK
c.RegisterType<IGreeter, JapaneseGreeter>("japanese");
c.RegisterType<IGreeter, EnglishGreeter>("english");
// IGreeterでjapaneseで登録したクラスのインスタンスを取得
var jpn = c.Resolve<IGreeter>("japanese");
Console.WriteLine(jpn.Greet()); // こんにちは
// IGreeterでenglishで登録したクラスのインスタンスを取得
var english = c.Resolve<IGreeter>("english");
Console.WriteLine(english.Greet()); // Hello
}
}
}
ふむ。インスタンスの生成をしてくれる賢いタイプセーフなHashMapって所か。んじゃ、DIコンテナらしく依存性を注入してもらうようにしてみる。IGreeterを使う、GreeterClientを作成する。
class GreeterClient
{
// IGreeter型の何かを依存性注入してもらう
[Dependency]
public IGreeter Greeter { get; set; }
public void Execute()
{
Console.WriteLine(this.Greeter.Greet());
}
}
Dependency属性がついているプロパティは、いい感じに依存性注入してくれるらしい。
試してみる。
var c = new UnityContainer();
// IGreeterの実装としてJapaneseGreeterを登録
c.RegisterType<IGreeter, JapaneseGreeter>();
// GreeterClientを登録
c.RegisterType<GreeterClient, GreeterClient>();
// GreeterClientを取得してExecuteを叩く
var client = c.Resolve<GreeterClient>();
client.Execute(); // こんにちはが出力される
GreeterClientのGreeterプロパティに自動的に値が設定されているのがわかる。
c.RegisterType<IGreeter, JapaneseGreeter>()からc.RegisterType<IGreeter, EnglishGreeter>()に変えると、Helloが出力される。
うんDIだね。