簡単なクラス間のDI実装
IDependencyResolver実装クラスであるNinjectDIResolverと、Global.asax上で設定が完了しているので、クラス間のDI実装も簡単に実施できます。簡単なサンプルを見てみましょう。
今まではPubsControllerとViews/Pubsに関する実装をしてきましたが、ここでIPubsRepositoryインターフェイスとPubsRepositoryクラス上に新しく機能を実装し、それをHomeControllerとViews/Home上で利用してみます(図7)。
今回は動作の確認ということでシンプルにControllerにアクセスした時間をインターフェイス越しに別クラスに渡して、そのクラスのメッセージと合わせて文字列を表示させるということを実施してみます。実行結果は図8のとおりです。
実装手順は以下のとおりです。
- インターフェイスの作成
- インターフェイスを実装したクラスを作成
- Controllerのコンストラクタ設定
- Global.asaxにDIコンテナを登録
順に解説します。
インターフェイスの作成
シンプルにメソッドを1つ定義します。
public interface ISendMessage { string SendMessage(string message); }
次に、このインターフェイスを実装したクラスを作成します。
インターフェイスを実装したクラスを作成
こちらもシンプルにISendMessageインターフェイスのメソッドのみ実装します。
public class SendMessageService:ISendMessage { public string SendMessage(string message) { return String.Format("現在の日時は{0}です。これはDIの実装例です。", message); } }
SendMessageメソッドは見たとおりで、パラメータとして渡される時間の文字列をプラスして文字列を返します。
次にControllerのコンストラクタ設定です。
Controllerのコンストラクタ設定
リポジトリパターンの時同様にコンストラクタの設定をします。
public class HomeController : Controller { private ISendMessage _sm; public HomeController(ISendMessage sendmessage) { _sm = sendmessage; } public ActionResult Index() { ViewBag.Message = "ASP.NET MVC へようこそ"; ViewBag.SendMessage = _sm.SendMessage(System.DateTime.Now.ToString()); return View(); } <中略> }
コンストラクタ設定の他に、View側でメッセージを表示させるためにViewBag.SendMessageに対してControllerにアクセスした時間をパラメータとして渡しています。
Global.asaxにDIコンテナを登録
IDependencyResolverの設定は完了しているので、Global.asax上に記載しているインターフェイスとクラスを紐づける記載をします。
protected void Application_Start() { // NinjectのStandarKernelオブジェクトの作成 IKernel _kernel = new StandardKernel(); // IPubsRepositoryとPubsRepositoryを紐づける _kernel.Bind<IPubsRepository>().To<PubsRepository>(); // ISendMessageとSendMessageServiceを紐づける _kernel.Bind<ISendMessage>().To<SendMessageService>(); // DIコンテナのリゾルバを登録 DependencyResolver.SetResolver(new NinjectDIResolver(_kernel)); <中略> }
ISendMessageにリクエストがある場合に都度SendMessageServiceオブジェクトをインジェクションします。
DIにより、本来はクラス間の依存関係があるため利用が難しいはずのMVCの関心の分離をさらに一歩進めて別のMVC上でも利用できることが確認できました。また、再利用性を考慮した場合、DIは有益であることもご理解いただけたのではないでしょうか。
クラス内にクラスのオブジェクトを持つ依存関係の発生はテストを重視するシナリオでは厄介な存在であり、DIを使用することでコードやファイルこそ複雑になりますが、テストの容易さはかなりの魅力になると言えます。
まとめ
今回はMVC 3におけるDI実装の基本について紹介しました。NinjectやUnityを使う場合は容易にDI実装が実現できます。今回は業務でも活用されるであろうデータアクセス部分にフォーカスを当てて解説しましたが、DI実装は他にもModel/View/Controller/Propertyなどさまざまな局面で利用可能です。興味がある方は本記事を足掛かりに実際に調べてみると良いでしょう。
なお、DIのキモはあくまでテストの容易さにあります。先にも記載したように次回はTipsを混ぜながら実際に今回作成したサンプルのテストの記述をしてみます。次回もお楽しみに。