OwinContext and why you can have many of them

One other reader did send yet another interesting question. The conversation started about AspNet Identity, but the question is actually about Owin and how it works.

See this bit of code from HttpContextBaseExtensions

public static IOwinContext GetOwinContext(this HttpContextBase context)
{
    IDictionary<string, object> environment = GetOwinEnvironment(context);

    if (environment == null)
    {
        throw new InvalidOperationException(
            Microsoft.Owin.Host.SystemWeb.Resources.HttpContext_OwinEnvironmentNotFound);
    }

    return new OwinContext(environment);
}

And the question goes like this:

As you can see, each time the OwinContext is pulled from the HttpContext, it returns a new context…. For an object that is named Context I found this rather strange behaviour. It also raises my eyebrows when I think of the term ‘CreatePerOwinContext’. What does this mean, when a new context is created every time. If you put this in a DI perspective, transient should be the name.

Let’s start from first part of the question.

Owin is all about dictionary. If you look on implementation of ApplicationBuilder, there are 2 dictionaries of objects and a list of middlewares:

private readonly IList<Tuple<Type, Delegate, object[]>> _middleware;
private readonly IDictionary<Tuple<Type, Type>, Delegate> _conversions;
private readonly IDictionary<string, object> _properties;

That’s a bit of a mouthful. Simple one is _conversion – this is a collection of rules how you can go from one type to another type: identified by Tuple with FromType and ToType and an actual delegate which does the conversion. Dictionary named _middleware is a list middleware objects with set of parameters – I’m not going to touch it here, as it is a magical unicorn I know nothing about.

If you look on HttpContextExtensions again, to create OwinContext the code queries dictionary HttpContext.Items with Owin key. HttpContext.Items is used “to organize and share data between an IHttpModule interface and an IHttpHandler interface during an HTTP request”.

Then reference to the object stored in HttpContext.Items is passed into constructor of OwinContext where the same reference to the dictionary is passed into OwinRequest and OwinResponse objects:

public OwinContext(IDictionary<string, object> environment)
{
    if (environment == null)
    {
        throw new ArgumentNullException("environment");
    }

    Environment = environment;
    Request = new OwinRequest(environment);
    Response = new OwinResponse(environment);
}

OwinRequest and OwinResponse are convenient wrappers to access objects from Environment dictionary. You’ll see a lot of methods like this in the above classes:

    /// <summary>
    /// Gets or set the HTTP method.
    /// </summary>
    /// <returns>The HTTP method.</returns>
    public virtual string Method
    {
        get { return Get<string>("owin.RequestMethod"); }
        set { Set("owin.RequestMethod", value); }
    }

    /// <summary>
    /// Gets or set the HTTP request scheme from owin.RequestScheme.
    /// </summary>
    /// <returns>The HTTP request scheme from owin.RequestScheme.</returns>
    public virtual string Scheme
    {
        get { return Get<string>("owin.RequestScheme"); }
        set { Set("owin.RequestScheme", value); }
    }

It turns out that OwinContext along with OwinRequest and OwinResponse are just strongly typed wrappers for dictionary that holds all the context data.

Actually, the documentation for OwinContext says pretty much the same:

This wraps OWIN environment dictionary and provides strongly typed accessors.

So don’t pick on the name. It is actually accessing a context data, but you can have multiple instances of wrappers for the same dictionary.

Dependency Injection in Owin

As I mentioned before Owin has it’s own little DI container that is used for internal needs.

Turns out this is not completely true. Owin itself does not have this. However, you can put objects into context dictionary and then retrieve them by the key, it is just a dictionary, it does not have much to it.

The DI functionality I referred to belongs to Asp.Net Identity. Here is an article about intended use. I would not recommend using it for anything else.

When you use app.CreatePerOwinContext<ApplicationDbContext>(ApplicationDbContext.Create), the code registers the delegate (method ApplicationDbContext.Create) in dictionary of middlewares. Once the Owin application is built (calling IAppBuilder.Build()) , this delegate is executed and instance of ApplicationDbContext is stored in OwinContext.Environment dictionary with type name as a key. Later when code is calling OwinContext.Get<ApplicationDbContext>(), this dictionary is looked by typename, casted to correct type and returned:

public virtual T Get<T>(string key)
{
    object value;
    return Environment.TryGetValue(key, out value) ? (T)value : default(T);
}

And if we are applying DI terms here, then your object is registered in per-request scope, as you would expect to be DbContext. If you are using a proper DI container, beware that if you register one object in Owin and the same typed of object in your container, these might be different instances and unexpected bugs/exceptions might happen.