私は MVC4 Web API プロジェクトを持っており、Mark Seemann のHyprlinkrコンポーネントを利用して、リンクされたリソースへの Uris を生成しています。(顧客 -> 住所など)。
Web API を使用した依存性注入に関する Mark のガイド (Ninject に合わせて適切に変更) には既に従いましたが、コントローラーにIResourceLinkerを注入するために何をすべきかがよくわかりません。
マークのガイドに従って、私のIHttpControllerActivator.Create作成メソッドは次のようになります。
IHttpController IHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
{
var controller = (IHttpController) _kernel.GetService(controllerType);
request.RegisterForDispose(new Release(() => _kernel.Release(controller)));
return controller;
}
Hyperlinkr のreadme で RouteLinkerの作成が提案されているのは、このメソッドです。残念ながら、これを Ninject に登録する方法がわかりません。
複数のバインディングが発生するため、以下のようにバインドすることはできません。
_kernel.Bind<IResourceLinker>()
.ToMethod(context => new RouteLinker(request))
.InRequestScope();
私は次のように再バインドを行いました:
_kernel.Rebind<IResourceLinker>()
.ToMethod(context => new RouteLinker(request))
.InRequestScope();
しかし、ninject バインディング グラフを変更することは、すべてのリクエストで実行するのが悪いことである可能性があることを懸念しています。
これを達成するための最良の方法は何ですか?
Paige Cookからのリクエストに応じて更新
ここで再バインドを使用しています:
IHttpController IHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
{
_kernel.Rebind<IResourceLinker>()
.ToMethod(context => new RouteLinker(request))
.InRequestScope();
var controller = (IHttpController) _kernel.GetService(controllerType);
request.RegisterForDispose(new Release(() => _kernel.Release(controller)));
return controller;
}
IHttpControllerActivator.Createは、すべての要求で呼び出されます。残りのバインディングは標準的な方法で作成されます。つまり、標準とは、Ninject.MVC3 nuget パッケージを使用して生成されたクラスを意味します。
私のコントローラーは次のようになります。
public class CustomerController : ApiController
{
private readonly ICustomerService _customerService;
private readonly IResourceLinker _linker;
public CustomerController(ICustomerService customerService, IResourceLinker linker)
{
_customerService = customerService;
_linker = linker;
}
public CustomerModel GetCustomer(string id)
{
Customer customer = _customerService.GetCustomer(id);
if (customer == null)
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
return
new CustomerModel
{
UserName = customer.UserName,
Firstname = customer.Firstname,
DefaultAddress = _linker.GetUri<AddressController>(c => c.Get(customer.DefaultAddressId)),
};
}
}