James Legan
James Legan

Reputation: 2063

Request Dependency Resolution in Web API

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

Answers (1)

James Legan
James Legan

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

Related Questions