Unityその2
コンストラクタ/プロパティインジェクションを実験君。
まずは、インジェクションされるクラスを用意します。
using Microsoft.Practices.Unity; public class ConstructorGreetingUser { IGreeting greeting; public ConstructorGreetingUser(IGreeting greeting) { this.greeting = greeting; } public void Say(string msg) { greeting.Say("Constructor:" + msg); } } public class PropertyGreetingUser { IGreeting greeting; [Dependency] public IGreeting Greeting { get { return greeting; } set { greeting = value; } } public void Say(string msg) { greeting.Say("Property:" + msg); } }
これをコンパイルしてGreetingUser.dllを作成します。ConstructorGreetingUserクラスはコンストラクタの引数がIGreetingなっていて、ここにインジェクションされます。一方、PropertyGreetingUserは、Greetingプロパティにカスタム属性が付いていることに気づきましたでしょうか。Unityはプロパティインジェクションをするためには、カスタム属性を付ける必要があるようです。(将来的には無くても出来るような記事をネットで見た気がしますが、失念)。あとは、設定ファイルを書いてインジェクションですが、XMLを書くのも面倒なのでIronPythonでやってしまうことにします。
import clr clr.AddReference('Microsoft.Practices.Unity') clr.AddReference('IGreeting') clr.AddReference('GreetingImpl') clr.AddReference('GreetingUser') import IGreeting import GreetingImpl import ConstructorGreetingUser import PropertyGreetingUser from Microsoft.Practices.Unity import * # コンテナの生成 container = UnityContainer() # 設定ファイルではなく、IronPythonコードでコンテナの設定を行う container.RegisterType[IGreeting, GreetingImpl]() # コンストラクタ インジェクション ctor = container.Resolve[ConstructorGreetingUser]() ctor.Say('Taro') # プロパティ インジェクション prop = container.Resolve[PropertyGreetingUser]() prop.Say('Hanako') # IronPythonで実装クラスを作成してみる class PyGreetingImpl(IGreeting): def Say(self, msg): print 'Py,', msg # 新たにコンテナを生成 container = UnityContainer() # IronPtyhonのクラスはRegisterTypeでは登録出来ない #container.RegisterType[IGreeting, PyGreetingImpl]() # インスタンスを作成して、RegisterInstanceを使うとIronPythonクラスが登録可能 # ただし、インタフェースを実装する場合のみ pygreeting = PyGreetingImpl() container.RegisterInstance[IGreeting](pygreeting) ctor = container.Resolve[ConstructorGreetingUser]() ctor.Say('Taro') prop = container.Resolve[PropertyGreetingUser]() prop.Say('Hanako') # 結果 # Hi, Constructor:Taro # Hi, Property:Hanako # Py, Constructor:Taro # Py, Property:Hanako
こんな感じ。設定ファイルを使うのは、コンパイルせずに変更したいというのが動機のほとんどなので、スクリプト言語が使えるのなら、XMLでちまちか設定を書くよりもコードで書いてしまった方が楽な気がしますが、そんなことありません?(^^;
個人的には全てを静的言語or動的言語にするより、お互いの得意分野で補完しあうのが良い気がします。例えば、C#を使ってきっちりとしたコンポーネントを作成し、DIコンテナとスクリプト言語を使ってオブジェクトの生成と依存関係の解決をさせるとか。