我有一个MVC (软托管)项目,它使用WebApi解决控制器依赖
它看起来像这样
public class PacientaiController : ODataController
{
private readonly IEntityRepo<Ent.Pacientas> repo;
public PacientaiController(IEntityRepo<Ent.Pacientas> repo)
{
this.repo = repo;
}
我试图解决的问题是如何将'OwinContex‘传递给一个回购。
public class PacientasEntityRepo:IEntityRepo<Pacientas>,IDisposable
{
public PacientasEntityRepo(IOwinContext ctx)
{
.........
如果我尝试在Startup.cs
中像这样注册它
Container.RegisterType<IOwinContext>(new InjectionFactory(o => HttpContext.Current.GetOwinContext()));
我得到一个空引用,说明HttpContext.Current
为空
这里的主要思想是将当前经过身份验证的用户传递给repo,因为Repo托管用于查询数据库的逻辑,具体取决于用户。(假设用户是Admin,则返回此数据,如果用户是guest,则返回此数据)
重点是-这是一个自我主机!
发布于 2015-01-08 02:23:28
让我们把为什么要进行这种设计放在一边,专注于问题:注入IOwinContext
您也可以使用GetOwinContext
方法从HttpRequestMessage
实例中获取它,但是您还需要以某种方式获取一个HttpRequestMessage
。
Unity不支持HttpRequestMessage
的开箱即用注入,但您可以使用一个自定义的DelegatingHandler
,它将当前的HttpRequestMessage
存储在容器中,如下所述:Inject WebAPI UrlHelper into service using Autofac
链接的问题是关于Autofac的,但您可以将其转移到Unity工作:
可以从Andrew Davey的答案中直接使用CurrentRequest
和CurrentRequestHandler
:
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);
}
}
然后,您只需向以下位置注册DelegatingHandler
:
httpConfiguration.MessageHandlers.Insert(0, new CurrentRequestHandler());
并在容器中注册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);
除了自定义委托处理程序之外,还有其他地方可以挂钩到Web.API以捕获HttpRequestMessage
。例如,您可以创建自己的IHttpControllerActivator
并使用ExecuteAsync
方法,如下所述:Dependency Injection in ASP.NET Web API 2
发布于 2015-01-05 22:18:21
在自托管应用程序中,您没有HttpContext。您需要另一种方法来移动状态。一种选择是使用自实现的HttpContext,如下所示:
https://github.com/danielcrenna/graveyard/tree/master/httpcontext-shim
发布于 2015-01-07 20:36:44
我认为问题是在调用Startup的时候HttpContext并不存在,所以你可能需要的是有一个Func,如下所示:
public class PacientasEntityRepo:IEntityRepo<Pacientas>,IDisposable
{
public PacientasEntityRepo(Func<IOwinContext> ctx)
{
.........
然后将Startup中的代码更改为:
Container.RegisterType<IOwinContext>(new InjectionFactory(() => HttpContext.Current.GetOwinContext()));
https://stackoverflow.com/questions/27723244
复制相似问题