Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

attaching linq to sql datacontext to httpcontext in business layer

I need my linq to sql datacontext to be available across my business/data layer for all my repository objects to access. However since this is a web app, I want to create and destroy it per request. I'm wondering if having a singleton class that can lazily create and attach the datacontext to current HttpContext would work. My question is: would the datacontext get disposed automatically when the request ends? Below is the code for what I'm thinking. Would this accomplish my purpose: have a thread-safe datacontext instance that is lazily available and is automatically disposed when the request ends?

public class SingletonDC
{
    public static NorthwindDataContext Default
    {
        get
        {
            NorthwindDataContext defaultInstance = (NorthwindDataContext)System.Web.HttpContext.Current.Items["datacontext"];
            if (defaultInstance == null)
            {
                defaultInstance = new NorthwindDataContext();
                System.Web.HttpContext.Current.Items.Add("datacontext", defaultInstance);
            }
            return defaultInstance;
        }
    }
}
like image 362
Riz Avatar asked Mar 20 '10 06:03

Riz


1 Answers

What you imagine makes sense - using the HTTP Request context to store stuff - but No, disposable objects stored in the current HttpContext will not auto-magically be disposed when the request ends. You will have to hande that yourself, somehow.

There is an "End Request" event that you can hook into easily, for example using code that you drop into Global.asax.cs. In your Application_EndRequest() method, you can call Dispose() manually on each object in the list that requires it.

One way to do it is to iterate through each item in the context, test for IDisposable, and then call Dispose if appropriate.

protected void Application_EndRequest(Object sender, EventArgs e)
{
    foreach (var key in HttpContext.Current.Items.Keys) 
    {
        var disposable = HttpContext.Current.Items[key] as IDisposable;
        if (disposable != null)
        { 
           disposable.Dispose();
           HttpContext.Current.Items[key] = null; 
        } 
    }
}

I think that oughtta do it. ASPNET doesn't do this for you automatically. Of course you need protection from exceptions and so on, before using this code in a real app.


Keith Craig of Vertigo wrote a relevant post on the topic a while ago, describing what you want to do as a pattern, in other words a way of doing things that ought to be repeated. He provides a class to help out with that, to lazy load the DB context and drop it into the current context. There are some pitfalls with the approach - you can read about them in the comment discussion on that post. Also there are a bunch of related articles cited in the comments.

like image 158
Cheeso Avatar answered Sep 23 '22 16:09

Cheeso