Ninject.MVC 2.2.0.3 (マージ後) を使用した MVC3 アプリケーションでは、リポジトリをコントローラーに直接注入する代わりに、ビジネスロジックを含むサービスレイヤーを作成し、そこにリポジトリを注入しようとしています。ninject-DependencyResolver を動的オブジェクトとしてサービス層に渡します (mvc も ninject も参照したくないため)。次に、GetService を呼び出して、NinjectHttpApplicationModule で指定したバインディングと有効期間を持つリポジトリを取得します。編集:要するに、失敗しました。
この場合、どのように IoC コンテナーをサービス層に渡すことができますか? (異なるアプローチも大歓迎です。)
編集:これは、回答とコメントをどのように理解するかを示す例です。
サービス ロケーター(アンチ) パターンを避け、代わりに依存性注入を使用する必要があります。たとえば、Northwind で製品とカテゴリの管理サイトを作成するとします。テーブル定義に従って、モデル、リポジトリ、サービス、コントローラー、およびビューを作成します。この時点で、サービスはリポジトリを直接呼び出します。ロジックはありません。機能の柱があり、ビューには生データが表示されます。これらのバインディングは NinjectMVC3 用に構成されています。
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<ICategoryRepository>().To<CategoryRepository>();
kernel.Bind<IProductRepository>().To<ProductRepository>();
}
リポジトリ インスタンスは、ProductController 内のコンストラクタ インジェクションの 2 つのレイヤを介して ninject によって作成されます。
private readonly ProductsService _productsService;
public ProductController(ProductsService productsService)
{
// Trimmed for this post: nullchecks with throw ArgumentNullException
_productsService = productsService;
}
および製品サービス:
protected readonly IProductRepository _productRepository;
public ProductsService(IProductRepository productRepository)
{
_productRepository = productRepository;
}
今のところサービスを分離する必要はありませんが、データベースをモックする準備ができています。
製品/編集でカテゴリのドロップダウンを表示するには、製品に加えてカテゴリを保持する ViewModel を作成します。
public class ProductViewModel
{
public Product Product { get; set; }
public IEnumerable<Category> Categories { get; set; }
}
ProductsService を作成するには、CategoriesRepository が必要になりました。
private readonly ICategoryRepository _categoryRepository;
// Changed constructor to take the additional repository
public ProductsServiceEx(IProductRepository productRepository,
ICategoryRepository categoryRepository)
{
_productRepository = productRepository;
_categoryRepository = categoryRepository;
}
public ProductViewModel GetProductViewModel(int id)
{
return new ProductViewModel
{
Product = _productRepository.GetById(id),
Categories = _categoryRepository.GetAll().ToArray(),
};
}
GET Edit-action を変更しreturn View(_productsService.GetProductViewModel(id));
、Edit-view をドロップダウンを表示するように変更します。
@model Northwind.BLL.ProductViewModel
...
@Html.DropDownListFor(pvm => pvm.Product.CategoryId, Model.Categories
.Select(c => new SelectListItem{Text = c.Name, Value = c.Id.ToString(), Selected = c.Id == Model.Product.CategoryId}))
これに関する1 つの小さな問題であり、私が Service Locator で迷子になった理由は、ProductController の他のアクション メソッドがカテゴリ リポジトリを必要としないことです。必要がない限り作成するのはもったいないし、論理的ではないと思います。何か不足していますか?