用Web API和Ninject注入IOwinContext
使用Web API 2和OWIN与Ninject进行托管。
我想将当前的IOwinContext注入到某些服务中(这样我就可以获得请求,让主体执行一些数据过滤)。
随着虚拟主机,我会,在过去,只是简单地使用HttpContext.Current,但这不是OWIN托管(和好消息)的选项。
这个SO问题解释了如何用Autofac做到这一点。 本质上,你创建一个依赖范围,然后在每个请求中调用Autofac的Registerinstance来将当前的IOwinContext注册到该依赖范围中,如下所示:
app.Use(async (ctx, next) =>
{
// this creates a per-request, disposable scope
using (var scope = container.BeginLifetimeScope(b =>
{
// this makes owin context resolvable in the scope
b.RegisterInstance(ctx).As<IOwinContext>();
}))
{
// this makes scope available for downstream frameworks
ctx.Set<ILifetimeScope>("idsrv:AutofacScope", scope);
await next();
}
});
这非常优雅。 有了Ninject和Ninject.Web.WebApi.OwinHosting,我已经为每个请求获得了一个命名范围,因此管理工作已经完成。 但是,我还没有找到任何方法在ninject中镜像AutoFac的RegisterInstance方法:这里的关键是这个绑定仅在这个特定的依赖范围内有效。
我已经阅读了Scope的各种选项,但是我发现的所有东西都依赖于能够声明常量或ToMethod。 我在这里要做的是说,“好吧,我现在有一个ninject依赖范围,如果有人从这个范围请求IOwinContext,给他们这个我已经拥有的实例。
注意
我明白我可以从我的控制器中获取当前上下文并传递它,但这相当于打破了我尝试做的目的; 我希望我的DbContext能够理解用户是谁,因此可以过滤数据。 而且,当然,一旦我可以获得IOwinContext,我实际上不会将它传递给DbContext,而是使用ToMethod或类似方法来提取ClaimsPrincipal,但超出了此问题的范围。
免责声明:这是一个黑客。 它有效,但感觉非常不洁。 在你的危险中使用。
本质上,您可以创建一个OwinContextHolder类,将其绑定到InRequestScope中,并使用DelegatingHandler将其填充到每个请求上。 像这样的东西:
public class OwinContextHolder
{
public IOwinContext OwinContext { get; set; }
}
public class OwinContextHolderModule : NinjectModule
{
public override void Load()
{
// Instead of a NinjectModule you can of course just register the service
this.Kernel.Bind<OwinContextHolder>().ToSelf().InRequestScope();
}
}
您的委托处理程序:
public class SetOwinContextHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var holder = request.GetDependencyScope().GetService(typeof(OwinContextHolder)) as OwinContextHolder;
if (holder != null)
{
holder.OwinContext = request.GetOwinContext();
}
return base.SendAsync(request, cancellationToken);
}
}
最后将DelegatingHandler添加到Startup类中:
public void Configuration(IAppBuilder app)
{
var webApiConfiguration = new HttpConfiguration();
webApiConfiguration.Routes.MapHttpRoute(...);
webApiConfiguration.MessageHandlers.Add(new SetOwinContextHandler());
app.UseNinjectMiddleware(CreateKernel);
app.UseNinjectWebApi(webApiConfiguration);
}
你现在可以将OwinContextHolder注入到你的类中。
请注意,如果您将API用于与主机分开的组件中,那么InRequestScope可能会遇到问题,并且无法正常工作(例如,每次请求一个错误时都会得到一个不同的对象)。 如果是这样,请参阅https://groups.google.com/forum/#!topic/ninject/Wmy83BhhFz8。
链接地址: http://www.djcxy.com/p/20189.html上一篇: Inject IOwinContext with Web API and Ninject
下一篇: Deep Learning Neural Networks for Time Series Prediction