webapi - web api en c#
Cómo pasar el contexto de Owin a un Repo que se inyecta en el controlador Api (3)
Creo que el problema es que HttpContext no existe en el momento en que se llama a Startup, por lo que probablemente lo que necesitas es tener un Func en su lugar, como este:
public class PacientasEntityRepo:IEntityRepo<Pacientas>,IDisposable
{
public PacientasEntityRepo(Func<IOwinContext> ctx)
{
.........
y luego cambie el código en Inicio a esto:
Container.RegisterType<IOwinContext>(new InjectionFactory(() => HttpContext.Current.GetOwinContext()));
Tengo un proyecto MVC WebApi owin (software alojado), que utiliza Unity para resolver dependencias de controlador
que se parecen a esto
public class PacientaiController : ODataController
{
private readonly IEntityRepo<Ent.Pacientas> repo;
public PacientaiController(IEntityRepo<Ent.Pacientas> repo)
{
this.repo = repo;
}
El problema que estoy tratando de resolver es cómo puedo pasar ''OwinContex'' a un Repo.
public class PacientasEntityRepo:IEntityRepo<Pacientas>,IDisposable
{
public PacientasEntityRepo(IOwinContext ctx)
{
.........
Si intento registrarlo así en el Startup.cs
Container.RegisterType<IOwinContext>(new InjectionFactory(o => HttpContext.Current.GetOwinContext()));
Obtengo una referencia nula, diciendo que HttpContext.Current
es NULL
La idea principal aquí es pasar el usuario autenticado actualmente al repositorio, ya que Repo aloja la lógica para consultar la base de datos, según el usuario. (diga si el usuario es administrador, luego devuelva estos datos, si el usuario es invitado - devuelva estos datos)
El punto es que este es un anfitrión propio!
Dejemos de lado por qué tiene este diseño y concéntrese en el problema: inyectando IOwinContext
:
también puede obtenerlo de una instancia de HttpRequestMessage
con el método GetOwinContext
, sin embargo, también necesita obtener un HttpRequestMessage
alguna manera.
Unity no admite la inyección del HttpRequestMessage
fuera de la caja, pero puede usar un DelegatingHandler
personalizado que almacena el HttpRequestMessage
actual en el contenedor como se describe aquí: Inyectar WebAPI UrlHelper en servicio usando Autofac
La pregunta vinculada es sobre Autofac, pero puede transferirla para trabajar con Unity:
El CurrentRequest
y el CurrentRequestHandler
se pueden usar de la respuesta de Andrew Davey tal como está:
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);
}
}
Entonces solo necesitas registrar el DelegatingHandler
con:
httpConfiguration.MessageHandlers.Insert(0, new CurrentRequestHandler());
Y registre el CurrentRequest
y IOwinContext
en el contenedor
container.RegisterType<CurrentRequest>(
new HierarchicalLifetimeManager());
container.RegisterType<IOwinContext>(
new HierarchicalLifetimeManager(),
new InjectionFactory(c => c.Resolve<CurrentRequest>().Value.GetOwinContext()));
httpConfiguration.DependencyResolver = new UnityHierarchicalDependencyResolver(container);
Además del controlador de delegación personalizado, hay otros lugares para enlazar con Web.API para capturar el HttpRequestMessage
por ejemplo, puede crear su propio IHttpControllerActivator
y usar el método ExecuteAsync
como se describe aquí: Inyección de dependencia en ASP.NET Web API 2
En una aplicación autoportada no tiene un HttpContext. Necesitas otra forma de mover el estado. Una opción es usar un HttpContext auto implementado como:
https://github.com/danielcrenna/graveyard/tree/master/httpcontext-shim