Come passare il contesto di Owin a un Repo che viene iniettato nel controller Api

Ho un progetto MVC WebApi owin (soft hosted), che utilizza Unity per risolvere le dipendenze dei controller

che assomiglia a questo

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

il problema che sto cercando di risolvere è come passare ‘OwinContex’ in un Repo.

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

Se provo a registrarlo in questo modo in Startup.cs

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

Ottengo un riferimento null, dicendo che HttpContext.Current è NULL

L’idea principale qui è di passare l’utente autenticato al repository, perché Repo ospita la logica per interrogare il database, a seconda dell’utente. (diciamo se l’utente è Admin, quindi restituisci questi dati, se l’utente è guest – restituisci questi dati)

Il punto è che si tratta di un auto-ospite!

    Lasciamo da parte il motivo per cui avete questo design e concentratevi sul problema: iniettando IOwinContext :

    puoi anche ottenerlo da un’istanza HttpRequestMessage con il metodo GetOwinContext , tuttavia devi anche ottenere un HttpRequestMessage qualche modo.

    Unity non supporta l’iniezione di HttpRequestMessage , ma puoi utilizzare un DelegatingHandler personalizzato che memorizza l’ HttpRequestMessage corrente nel contenitore come descritto qui: Iniettare UrlHelper WebAPI in servizio utilizzando Autofac

    La domanda collegata riguarda Autofac ma puoi trasferirlo per lavoro con Unity:

    CurrentRequest e CurrentRequestHandler possono essere utilizzati dalla risposta di Andrew Davey così com’è:

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

    Quindi devi solo registrare il DelegatingHandler con:

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

    E registrare CurrentRequest e IOwinContext nel contenitore

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

    Oltre al gestore di delega personalizzato, ci sono altri posti da colbind a Web.API per acquisire HttpRequestMessage ad esempio è ansible creare il proprio IHttpControllerActivator e utilizzare il metodo ExecuteAsync come descritto qui: Iniezione delle dipendenze in Web API ASP.NET 2

    In un’applicazione selfhosted non hai un HttpContext. Hai bisogno di un altro modo per spostare lo stato intorno. Un’opzione è quella di utilizzare un HttpContext implementato come:

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

    Penso che il problema è che HttpContext non esiste al momento dell’avvio di Startup, quindi quello che probabilmente ti serve è avere un Func, come questo:

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

    e quindi modificare il codice in avvio a questo:

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