How to pass Owin context to a Repo being injected into Api controller

后端 未结 4 476
挽巷
挽巷 2020-12-08 21:52

I\'ve got a MVC WebApi owin (soft hosted) project, that uses Unity for resolving controller dependencies

which look like this

public class PacientaiC         


        
相关标签:
4条回答
  • 2020-12-08 21:58

    In a selfhosted application you do not have a HttpContext. You need an other way to move the state around. An option is to use a self implemented HttpContext like:

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

    0 讨论(0)
  • 2020-12-08 22:03

    In my Asp.Net Mvc (AutoFac) project (not core) i have used below registeration andthat was successed

    builder.RegisterType<OwinContext>().AsImplementedInterfaces().InstancePerRequest();
    
    0 讨论(0)
  • 2020-12-08 22:05

    I think the problem is that HttpContext does not exist at the time Startup is called, so what you probably need, is to have a Func instead, like this:

    public class PacientasEntityRepo:IEntityRepo<Pacientas>,IDisposable
    {
        public PacientasEntityRepo(Func<IOwinContext> ctx)
        {
        .........
    

    and then change the code in Startup to this:

    Container.RegisterType<IOwinContext>(new InjectionFactory(() => HttpContext.Current.GetOwinContext()));
    
    0 讨论(0)
  • 2020-12-08 22:11

    Lets put aside why you have this design and concentrate to the problem: injecting the IOwinContext:

    you can also get it from a HttpRequestMessage instance with the GetOwinContext method, however you also need to get a HttpRequestMessage somehow.

    Unity does not support injection of the HttpRequestMessage out of the box but you can use a custom DelegatingHandler which stores the current HttpRequestMessage in the container as described here: Inject WebAPI UrlHelper into service using Autofac

    The linked question is about Autofac but you can transfer it for work with Unity:

    The CurrentRequest and the CurrentRequestHandler can be used from Andrew Davey's answer as it is:

    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);
        }
    }
    

    Then you just need to register the DelegatingHandler with:

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

    And register the CurrentRequest and IOwinContext in the container

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

    Beside the custom delegation handler there are other places to hook into Web.API to capture the HttpRequestMessage for example you can create your own IHttpControllerActivator and use the ExecuteAsync method as described here: Dependency Injection in ASP.NET Web API 2

    0 讨论(0)
提交回复
热议问题