50,000英尺概述:
IIS托管的Web API(OWIN)。
在OWIN中间件中,我做了很多事情(API密钥验证,以便验证请求,创建原则等......)。
我使用Unity作为我的容器。一旦我真正进入我的控制器,我正在注入一个服务类,它从我的控制器中抽象出我的存储库。在服务层,我执行审计跟踪,历史记录等操作,以便在我注入服务类的任何地方,我都能获得额外的好处。
这一切都有效,生活是美好的,yada yada yada。
...直到
我有一个自定义标头值(X-OnBehalfOf),API的调用者使用正在执行特定请求的用户ID填充该标头值。这是应用程序的要求,其实现非常简单。
我可以从我有权访问请求的任何地方轻松检索此值(OWIN中间件,控制器等...)。然而,当我试图在我的服务层中获取该值时,我试图解决的问题就出现了。
由于我正在使用我的容器来解析服务类的实例,我最初的解决方案是实现像IHeaderProvider这样的东西并将其注入到服务类的构造函数中,但我似乎无法弄清楚如何获取对该类中的Request的引用,因为它已不在管道中。
我确信有一种明显的方法可以做到这一点,但我一直遇到问题。有没有人知道如何获得该引用而不必重新启动它以便我可以利用我的DI容器为我做这项工作?
答案 0 :(得分:4)
看起来我只需要把它写在纸上。这就是我解决它的方法:
容器:
container.RegisterType<IHeaderProvider, HeaderProvider>(new HierarchicalLifetimeManager());
container.RegisterType<HttpContextBase>(new InjectionFactory(c => new HttpContextWrapper(HttpContext.Current)));
IHeaderProvider:
public interface IHeaderProvider
{
Guid GetOnBehalfOf();
}
HeaderProvider:
public class HeaderProvider : IHeaderProvider
{
private readonly HttpContextBase _httpContextBase;
public HeaderProvider(HttpContextBase httpContextBase)
{
_httpContextBase = httpContextBase;
}
public Guid GetOnBehalfOf()
{
var xOnBehalfOf = _httpContextBase.Request.Headers.Get("X-OnBehalfOfId");
Guid userId;
if (string.IsNullOrWhiteSpace(xOnBehalfOf))
throw new Exception("Missing user ID");
if (Guid.TryParse(xOnBehalfOf, out userId))
{
return userId;
}
throw new Exception("Invalid user ID");
}
}