我有一个 MVC4 Web API 项目,我利用 Mark Seemann 的Hyprlinkr组件生成链接资源的 Uris。(例如客户 -> 地址)。
我已经按照 Mark 的关于使用 Web API 进行依赖注入的指南(针对 Ninject 进行适当更改)进行操作,但我不太清楚应该如何将IResourceLinker注入到我的控制器中。
按照 Mark 的指南,我的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;
}
Hyprlinkr 自述文件建议在这种方法中创建RouteLinker。不幸的是,我不确定如何使用 Ninject 注册它。
我不能像下面这样绑定,因为这会导致多个绑定:
_kernel.Bind<IResourceLinker>()
.ToMethod(context => new RouteLinker(request))
.InRequestScope();
我有这样的重新绑定工作:
_kernel.Rebind<IResourceLinker>()
.ToMethod(context => new RouteLinker(request))
.InRequestScope();
但我担心更改 ninject 绑定图对于每个请求都可能是一件坏事。
实现这一目标的最佳方法是什么?
应佩奇库克的要求更新
我在这里使用重新绑定:
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)),
};
}
}