C# WebApi2控制器方法中的条件绑定
我将Ninject与以下软件包一起使用:C# WebApi2控制器方法中的条件绑定,c#,asp.net-web-api,dependency-injection,ninject,C#,Asp.net Web Api,Dependency Injection,Ninject,我将Ninject与以下软件包一起使用: 尼尼特 Ninject.MVC5 Ninject.Web.Common(和Common.WebHost) Ninject.Web.WebApi(和WebApi.WebHost) 我有一个WebApi2控制器,如下所示。我的Get() 问题: 只有在调用某些api方法的情况下,我才能有选择地绑定接口吗?是通过使用属性还是 public class FooController : ApiController { public IMyFooSer
- 尼尼特
- Ninject.MVC5
- Ninject.Web.Common(和Common.WebHost)
- Ninject.Web.WebApi(和WebApi.WebHost)
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();
}
}
我注意到To()
有许多.When()
选项。也许我可以利用这个来说。当(/*Controller=Foo,Action=Post*/)
之前有人问过类似的问题时。退房因此,对于您的特定情况,您可以将IsRouteValueDefined方法(您可以考虑一些更好的命名,我建议使用IsRoutePoitingTo)从原始答案修改为类似这样的内容(如果它适用于WebApi,您可以重新访问,但也可以确定有一种方法可以获取当前路由):
而绑定将类似于:
kernel.Bind<IMyFooService>()
.To<MyConcreteService>()
.When(x=> IsRouteValueDefined("foo", "get"));
kernel.Bind()
.至()
.When(x=>IsRouteValueDefined(“foo”,“get”));
只是不确定“get”对于ApiController实际的路由可能是什么,如果是的话,只需使用string.Empty作为“action”参数。你可以用你的特定项目来检查。由于您不需要默认注入(这在原始答案中存在),我只是放弃了它。最简单、可能也是最简洁的方法是使用专门为这个用例设计的方法-引用文档:
使用延迟初始化延迟创建大型或大型
资源密集型对象,或执行资源密集型
任务,特别是在可能不会发生此类创建或执行时
在程序的生命周期内
对Lazy
注入的支持随附(另请参见上的Wiki页面)。安装它,您应该准备好注入Lazy
调整控制器的代码,如下所示:
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();
}
}
公共类FooController:ApicController{
公共服务;
公共FooController(惰性fooService){
this.fooService=fooService;
}
public JsonResult Get(){}
公共异步任务发布([FromBody]IList foos){
var didMyFoo=this.fooService.Value.DoTheFoo();
}
}
请注意,实际服务是通过Lazy
上的.Value
属性访问的。第一次访问此属性时,将检索实例。请阅读本文。有人已经提出了类似的建议,但我相信这就是您正在寻找的设计。是的,对于这种特殊情况,假设MyConcreteService的初始化是一项非常繁重的操作,您希望在不需要的地方跳过它,我认为Lazy是最好的选择。我很嫉妒这个想法没有出现在我的脑海里,而是直接回答了这个问题:)这肯定应该被标记为正确的答案!
kernel.Bind<IMyFooService>()
.To<MyConcreteService>()
.When(x=> IsRouteValueDefined("foo", "get"));
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();
}
}