Reputation: 2063
50,000ft overview:
Web API (OWIN) hosted by IIS.
In OWIN Middleware I do a bunch of things (API Key validation in order to authenticate a request, create principles, etc...).
I am using Unity as my container. Once I actually get to my controllers, I am injecting a service class which abstracts my repository from my controllers. In the service layer I do things like audit tracking, history logging and the like so that everywhere I inject my service classes, I get the added benefit.
This all works, life is good, yada yada yada.
Until...
I have a custom header value (X-OnBehalfOf) which the caller of the API populates with the user ID that a particular request is being performed by. This is a requirement of the application and its implementation is pretty straight forward.
I can easily retrieve this value from anywhere I have access to the Request (OWIN Middleware, controller, etc...). The problem I am trying to solve however comes in when trying to get that value in my service layer.
Since I am using my container to resolve the instance of the service class, I intitially though the best solution would be to implement something like IHeaderProvider and inject that into the constructor of the service class, but I cannot seem to figure out how to get a reference to the Request in that class since it is out of the pipeline.
I am sure there is an obvious way to do this but I keep running into issues. Does anyone know how to get that reference without having to new it up so that I can leverage my DI container to do the work for me?
Upvotes: 3
Views: 957
Reputation: 2063
It would appear I just needed to put it down on paper. This is how I solved it:
Container:
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");
}
}
Upvotes: 4