前回はコントローラのコンストラクタでリポジトリのインスタンスを受け取るようにしてましたが、今回は IServiceLocator を経由してリポジトリのインスタンスを取得するようにしてみます。
ServiceLocator を使うと UnityContainer で登録したクラスのインスタンスを自由に取得することが出来るようになるので、コンストラクタ以外でも好きに使うことが出来ます。
まずはコントローラのコンストラクタ引数を IServiceLocator に変更して、IProductRepository のインスタンスを GetInstance メソッドで取得するように書き換えます。
public class ProductController { public ProductController(IServiceLocator serviceLocator) { _productRepository = serviceLocator.GetInstance<IProductRepository>(); } private readonly IProductRepository _productRepository; public ActionResult Index() { var list = _productRepository.GetAll(); return View(list); } }
しかし、これで実行すると以下のような実行時エラーが表示されてしまいます。
これは IServiceLocator がインジェクションされていないのが原因です。なので Global.asax.cs の Application_Start にコードを追加します。
var container = new UnityContainer(); // IProductRepository には ProductRepository を使う container.RegisterType<IProductRepository, ProductRepository>(); // ServiceLocator を作成、登録 var serviceLocator = new UnityServiceLocator(container); ServiceLocator.SetLocatorProvider(() => serviceLocator); // リゾルバを登録 DependencyResolver.SetResolver(new UnityDependencyResolver(container));
UnityServiceLocator を生成して SetLocatorProvider に登録するコードを追加しました。これでもう一度実行してみます。
IServiceLocator のインスタンスと IProductRepository のインスタンスの両方が取得出来ました。