21

I need a way to store a logging object per request. With HttpContext I would add this to the items Dictionary. I don't want to bring HttpContext into this if I can help it. The below code is what I propose for a Unity LifeTimeManager that will store objects in OwinContext's Environment property, which I have access to with my Owin middleware.

public class OwinContextLifetimeManager : LifetimeManager
{
    private string key = (new Guid()).ToString();
    private IDictionary<string, object> environment;

    public OwinContextLifetimeManager(IDictionary<string, object> environment)
    {
        this.environment = environment;
    }

    public override object GetValue()
    {
        if (environment != null && environment.ContainsKey(key))
            return environment[key];
        else
            return null;
    }

    public override void RemoveValue()
    {
        if (environment != null)
            environment.Remove(key);
    }

    public override void SetValue(object newValue)
    {
        if (environment != null)
            environment[key] = newValue;
    }
}

Then I can use it like this from my middleware:

container.RegisterType<IRequestLog, RequestLog>(new OwinContextLifetimeManager(environment));

It occurs to me that I can choose whatever key I want except those that already are reserved by Owin. Is there any reason I should not be using the OwinContext.Environment for this purpose? The MSDN documentation is vague on the best practices of this.

Darrel Miller's response here: How should I store per request data when using OWIN to Self-Host ASP.NET Web API leads me to believe the properties collection on the request object is the way to go. How can I access this object from middleware?

Community
  • 1
  • 1
codetoast
  • 293
  • 1
  • 2
  • 9
  • I have edited your title. Please see, "[Should questions include “tags” in their titles?](http://meta.stackexchange.com/questions/19190/)", where the consensus is "no, they should not". – John Saunders Dec 08 '14 at 22:42
  • 1
    I know this is an old question, but I'd just like to note where you generate your key `new Guid()` should be `Guid.NewGuid()`. `new Guid()` creates an empty guid (all zeros - `Guid.Empty`) every time. – RJ Cuthbertson Sep 15 '15 at 14:54
  • Good to know. Turns out since it saves it in the context of the request, I just used a constant instead of saving an ID. – codetoast Sep 15 '15 at 15:12

1 Answers1

20

OWIN environment dictionary can be used to store per-request data. Properties collection of the request object can be used to do the same.

The main difference is OWIN environment dictionary is an OWIN concept and is applicable to any middleware running in a OWIN host. Properties collection of the request object is an ASP.NET Web API concept and is applicable only to that specific framework.

BTW, ASP.NET Web API itself runs as a middleware in OWIN pipeline. So, to answer your question, you cannot access the request properties collection of Web API from your middleware because it is applicable only to Web API middleware (or that specific framework).

If you want to write your cross-cutting concern stuff as OWIN middleware you have to use OWIN environment dictionary. If Web API extension points like a filter or a message handler is okay, then you can use the properties collection.

Obviously, anything you write leveraging Web API extension points is applicable only to Web API whereas OWIN middleware is applicable to any kind of app running in OWIN pipeline and that includes Web API.

Luke Puplett
  • 42,091
  • 47
  • 181
  • 266
  • 4
    Much text, little sense. More arguments: Concurrency? HttpContext.Current.Items vs Owin Environment differences? Owin FILO and importance of registering middlewares.. Wish to hear more about concrete things rather than "Web API uses" => We should use too.. – Cristian E. Feb 03 '15 at 18:13