如何将Owin上下文传递给注入Api控制器的Repo

我有一个MVC WebApi owin(软托管)项目,它使用Unity来解析控制器依赖项

看起来像这样

public class PacientaiController : ODataController { private readonly IEntityRepo repo; public PacientaiController(IEntityRepo repo) { this.repo = repo; } 

我试图解决的问题是 – 如何将’OwinContex’传递给回购。

 public class PacientasEntityRepo:IEntityRepo,IDisposable { public PacientasEntityRepo(IOwinContext ctx) { ......... 

如果我尝试在Startup.cs注册它

 Container.RegisterType(new InjectionFactory(o => HttpContext.Current.GetOwinContext())); 

我得到一个空引用,说HttpContext.Current是NULL

这里的主要思想是将当前经过身份validation的用户传递给repo,因为Repo托管逻辑以查询数据库,具体取决于用户。 (如果用户是Admin,则返回此数据,如果用户是guest – 返回此数据)

关键是 – 这是一个自我主持人!

让我们放下为什么你有这个设计并专注于问题:注入IOwinContext

您也可以使用GetOwinContext方法从HttpRequestMessage实例获取它,但是您还需要以某种方式获取HttpRequestMessage

Unity不支持开箱即用的HttpRequestMessage注入,但您可以使用自定义DelegatingHandler ,它将当前HttpRequestMessage存储在容器中,如下所述: 使用Autofac将WebAPI UrlHelper注入服务

链接的问题是关于Autofac,但您可以将其转移到Unity工作:

CurrentRequestCurrentRequestHandler可以从Andrew Davey的答案中使用,因为它是:

 public class CurrentRequest { public HttpRequestMessage Value { get; set; } } public class CurrentRequestHandler : DelegatingHandler { protected async override System.Threading.Tasks.Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { var scope = request.GetDependencyScope(); var currentRequest = (CurrentRequest)scope.GetService(typeof(CurrentRequest)); currentRequest.Value = request; return await base.SendAsync(request, cancellationToken); } } 

然后你只需要注册DelegatingHandler

 httpConfiguration.MessageHandlers.Insert(0, new CurrentRequestHandler()); 

并在容器中注册CurrentRequestIOwinContext

 container.RegisterType( new HierarchicalLifetimeManager()); container.RegisterType( new HierarchicalLifetimeManager(), new InjectionFactory(c => c.Resolve().Value.GetOwinContext())); httpConfiguration.DependencyResolver = new UnityHierarchicalDependencyResolver(container); 

除了自定义委托处理程序之外,还有其他地方可以挂钩到Web.API来捕获HttpRequestMessage ,例如,您可以创建自己的IHttpControllerActivator并使用此处所述的ExecuteAsync方法: ASP.NET Web API 2中的dependency injection

在自托管应用程序中,您没有HttpContext。 你还需要另一种方法来改变状态。 一个选项是使用自我实现的HttpContext,如:

https://github.com/danielcrenna/graveyard/tree/master/httpcontext-shim

我认为问题是在调用Startup时HttpContext不存在,所以你可能需要的是改为使用Func,如下所示:

 public class PacientasEntityRepo:IEntityRepo,IDisposable { public PacientasEntityRepo(Func ctx) { ......... 

然后将Startup中的代码更改为:

 Container.RegisterType(new InjectionFactory(() => HttpContext.Current.GetOwinContext()));