我正在使用Ninject和以下软件包:
我有一个WebApi2控制器,如下所示。我的Get()
方法必须具有高效性,并且不依赖于IMyFooService
的值,因此在请求Get()
时,我不关心它是否被注入。
问题:
只有在调用某些api方法时,我才有选择性地绑定接口的方法吗?是通过使用属性还是......?
public class FooController : ApiController {
public IMyFooService fooService;
public FooController(IMyFooService fooService) {
this.fooService = fooService;
}
[NonDependent] // Don't really care about the value of fooService
public JsonResult Get() {}
[Dependent] // Must have valid dependency injection
public async Task<JsonResult> Post([FromBody] IList foos) {
var didMyFoo = this.fooService.DoTheFoo();
}
}
这是我的NinjectWebCommon.cs
:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IMyFooService>().To<MyConcreteService>().InRequestScope();
}
我注意到To<T>()
有很多.When()
选项。也许我可以利用这个来说.When(/* Controller = Foo, Action = Post */)
。
答案 0 :(得分:4)
最简单,也可能是最简洁的方法是使用完全针对此用例的Lazy<T>
- 引用文档:
使用延迟初始化来推迟创建大型或 资源密集型对象,或资源密集型的执行 任务,特别是当这种创建或执行可能不会发生时 在该计划的整个生命周期中。
支持Lazy<T>
注入Ninject.Extensions.Factory(另见Lazy<T>
上的Wiki页面)。安装它nuget package,您应该准备好注入Lazy<T>
。
按如下方式调整控制器的代码:
public class FooController : ApiController {
public Lazy<IMyFooService> fooService;
public FooController(Lazy<IMyFooService> fooService) {
this.fooService = fooService;
}
public JsonResult Get() {}
public async Task<JsonResult> Post([FromBody] IList foos) {
var didMyFoo = this.fooService.Value.DoTheFoo();
}
}
请注意,.Value
上的 Lazy<T>
属性访问了实际服务。首次访问此属性时,将检索实例。
答案 1 :(得分:0)
前段时间已经提出了类似的问题。检查this。所以对于你的特殊情况你可以修改IsRouteValueDefined方法(你可以考虑一些更好的命名,我会建议像IsRoutePoitingTo这样的东西)从原始答案到这样的东西(你可能会重新审视,如果它适用于WebApi,但肯定有一个获得当前路线的方法):
public static bool IsRouteValueDefined(string controller, string action)
{
var mvcHanlder = (MvcHandler)HttpContext.Current.Handler;
var routeValues = mvcHanlder.RequestContext.RouteData.Values;
var containsRouteKey = routeValues.ContainsKey(routeKey);
if (routeValue == null)
return containsRouteKey;
return containsRouteKey &&
routeValues["controller"].ToString().Equals(controller, StringComparison.InvariantCultureIgnoreCase) &&
routeValues["action"].ToString().Equals(action, StringComparison.InvariantCultureIgnoreCase);
}
绑定看起来像:
kernel.Bind<IMyFooService>()
.To<MyConcreteService>()
.When(x=> IsRouteValueDefined("foo", "get"));
只是不确定&#34;得到&#34;对于ApiController,实际路由可以是http://website.com/foo/,如果是这样,只需使用string.Empty作为&#34; action&#34; PARAM。您可以使用您的特定项目进行检查。因为你不需要默认注射(原始答案中存在) - 我只是放弃了它。