This is a migrated thread and some comments may be shown as answers.

ContextFactory when HttpContext.Current goes null

3 Answers 441 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Eric
Top achievements
Rank 1
Eric asked on 03 Jul 2012, 08:01 PM
I have a theoretical question. I'm currently using nHIbernate and the nHibernate session is tied to the HttpContext.Current. My problem is, when I create a new thread, HttpContext.Current is becoming null and my session is disappearing. I could probably try to change my session management to create a new session HttpContext is null and then save the session somewhere else, but I'm straying from my question.

I'm curious if I have an object that's been loaded while the HttpContext.Current is not null, but then becomes null, can I continue to use the object?

Can I do something like the following without an exception. Because nHibernate is now giving me a "no session" error.

public class MyClass() {
    private Product _product;
     
    public MyClass(Product product) {
        _product = product;
    }
     
    public DoSomething() {
        Thread thread = new Thread(DoSomethingAsync);
        thread.IsBackground = true;
        thread.Start();
    }
     
    private DoSomethingAsync() {
        // HttpContext.Current will be null here
        Logger.Info(product.Category.Name);
    }
}
 
// Can I call this line elsewhere in my application?
new MyClass(product).DoSomething();

If so, I may ditch nHibernate and give OpenAccess a try.

Thanks,
Eric

3 Answers, 1 is accepted

Sort by
0
Viktor Zhivkov
Telerik team
answered on 05 Jul 2012, 12:14 PM
Hi Eric,

Thank you for your interest in our product.

Please note that we are not referring to HttpContext.Current anywhere in OpenAccess
Of course the best way to see that OpenAccess can satisfy your needs is to give it a try and do a sample scenario like the one that you have described. 
We are using per process (as opposed to per thread) caching of the underlying data access infrastructure and we usually create a new instance of the data context for each HTTP request (especially for services). The creation of the context itself is considered a lightweight and fast operation. You can implement different strategies for data context reuse, but my suggestion is to get first an introduction to OpenAccess using our online documentation and OpenAccess SDK examples.

If you have any additional questions, you are welcome to post them in our forums.

All the best,
Viktor Zhivkov
the Telerik team
OpenAccess ORM Q2'12 Now Available! Get your hands on all the new stuff.
0
Eric
Top achievements
Rank 1
answered on 05 Jul 2012, 02:46 PM
I was looking at the "Managing the OpenAccessContext" sample in the OpenAccess SDK and it stores the context in HttpContext.Current. That's why I was concerned what would happen when HttpContext.Current became null.

public class ContextModule : IHttpModule {
    public const string ContextKey = "DataContext";
     
    public static NorthwindContext GetContext() {
        IDictionary contextItems = HttpContext.Current.Items;
        if (contextItems == null || !contextItems.Contains(ContextModule.ContextKey))
            return null;
 
        return contextItems[ContextModule.ContextKey] as NorthwindContext;
    }
 
    public void Dispose() { }
 
    public void Init(HttpApplication context) {
        context.BeginRequest += new EventHandler(this.OnBeginRequest);
        context.EndRequest += new EventHandler(this.OnEndRequest);
    }
 
    private void OnBeginRequest(object sender, EventArgs e) {
        HttpContext.Current.Items[ContextModule.ContextKey] = new NorthwindContext();
    }
 
    private void OnEndRequest(object sender, EventArgs e) {
        this.CommitTransaction();
        this.DisposeContext();
        this.ClearHttpContextItem();
    }
 
    private void CommitTransaction() {
        NorthwindContext context = ContextModule.GetContext();
        if (context != null)
            context.SaveChanges();
    }
 
    private void DisposeContext() {
        NorthwindContext context = ContextModule.GetContext();
        if (context != null)
            context.Dispose();
    }
 
    private void ClearHttpContextItem() {
        IDictionary contextItems = HttpContext.Current.Items;
        if (contextItems == null || !contextItems.Contains(ContextModule.ContextKey))
            return;
 
        contextItems.Remove(ContextModule.ContextKey);
    }
}

Eric
0
Viktor Zhivkov
Telerik team
answered on 10 Jul 2012, 02:52 PM
Hello Eric,

The sample you have examined shows how to reuse a single context in several methods/classes and reduce the overhead of creation of the instance.
In the ContextFactory class of the DataLayer project of the example you can see how we suggest developers should resolve the cached (if any) data context instance:
public static NorthwindContext GetContextPerRequest()
{
    HttpContext httpContext = HttpContext.Current;
    if (httpContext == null)
    {
        return new NorthwindContext();
    }
    else
    {
        int contextId = Thread.CurrentContext.ContextID;
        int hashCode = httpContext.GetHashCode();
        string key = string.Concat(hashCode, contextId);
 
        NorthwindContext context = httpContext.Items[key] as NorthwindContext;
        if (context == null)
        {
            context = new NorthwindContext();
            httpContext.Items[key] = context;
        }
                 
        return context;
    }
}
The code above can handle very well the case when HttpContext.Current is null.

I hope that will clear the topic and enable you to continue your journey with OpenAccess.

All the best,
Viktor Zhivkov
the Telerik team
OpenAccess ORM Q2'12 Now Available! Get your hands on all the new stuff.
Tags
General Discussions
Asked by
Eric
Top achievements
Rank 1
Answers by
Viktor Zhivkov
Telerik team
Eric
Top achievements
Rank 1
Share this question
or