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

Mar*_*rty 19 c# unity-container owin asp.net-web-api2

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

看起来像这样

public class PacientaiController : ODataController
    {
        private readonly IEntityRepo<Ent.Pacientas> repo;

        public PacientaiController(IEntityRepo<Ent.Pacientas> repo)
        {
            this.repo = repo;
        }
Run Code Online (Sandbox Code Playgroud)

我试图解决的问题是 - 如何将'OwinContex'传递给回购.

public class PacientasEntityRepo:IEntityRepo<Pacientas>,IDisposable
    {
        public PacientasEntityRepo(IOwinContext ctx)
        {
        .........
Run Code Online (Sandbox Code Playgroud)

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

Container.RegisterType<IOwinContext>(new InjectionFactory(o => HttpContext.Current.GetOwinContext()));
Run Code Online (Sandbox Code Playgroud)

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

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

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

nem*_*esv 25

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

你也可以从一个HttpRequestMessage带有该GetOwinContext方法的实例中获取它,但是你也需要以HttpRequestMessage某种方式得到它.

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

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

CurrentRequestCurrentRequestHandler可以使用安德鲁·戴维的回答,因为它是:

public class CurrentRequest
{
    public HttpRequestMessage Value { get; set; }
}

public class CurrentRequestHandler : DelegatingHandler
{
    protected async override System.Threading.Tasks.Task<HttpResponseMessage> 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你只需要注册DelegatingHandler:

httpConfiguration.MessageHandlers.Insert(0, new CurrentRequestHandler());
Run Code Online (Sandbox Code Playgroud)

并注册CurrentRequest,并IOwinContext在容器

container.RegisterType<CurrentRequest>(
            new HierarchicalLifetimeManager());

container.RegisterType<IOwinContext>(
    new HierarchicalLifetimeManager(),
    new InjectionFactory(c => c.Resolve<CurrentRequest>().Value.GetOwinContext()));

httpConfiguration.DependencyResolver = new UnityHierarchicalDependencyResolver(container);
Run Code Online (Sandbox Code Playgroud)

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