Fra*_*ans 7 ninject asp.net-web-api owin
使用Ninject的Web API 2和OWIN托管.
我想将当前的IOwinContext注入某些服务(因此我可以获取请求以使主体进行一些数据过滤).
使用Web Hosting,在过去,我会使用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();
}
});
Run Code Online (Sandbox Code Playgroud)
那很优雅.使用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();
}
}
Run Code Online (Sandbox Code Playgroud)
您的委托处理程序:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
最后将 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);
}
Run Code Online (Sandbox Code Playgroud)
您现在可以将 OwinContextHolder 注入到您的类中。
请注意,如果您的 API 位于与主机不同的程序集中,则可能会遇到 InRequestScope 无法正常工作的问题(例如,每次请求一个对象时都会得到一个不同的对象,并且没有错误)。如果您这样做,请参阅https://groups.google.com/forum/#!topic/ninject/Wmy83BhhFz8。
| 归档时间: |
|
| 查看次数: |
2201 次 |
| 最近记录: |