3

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?

1 Answer 1

4

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");
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

This is a great solution! You should mark it as the answer.
Thanks! I often don't mark my own findings as answers because it feels odd :). Hope it helped.
HierarchicalLifetimeManager is not the correct lifetime option I think. I suggest using PerResolveLifetimeManager.
How in self-host ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.