Search This Blog

Tuesday, March 05, 2013

Passing data with OperationContext in WCF

I needed a way to pass data with OperationContext through out the WCF session so that I can access it anywhere in my web services code. While looking for solutions in stackoverflow, I found this. And best solution is directed to this. A lovely and neat work from Valeriu Caraulean. Thank you for posting such a good solution on your blog. You should check out his blog. It seems awesome.

I am posting the solution here, just in case the blog goes offline for no reason.




HttpContext Idiom for Windows Communication Foundation.


WCF infrastructure allows you to store context sensitive data in InstanceContext of the service instance. For that you should implement from IExtension and plug that class into WCF’s infrastructure in any of available ways.
When I worked on a class that can store contextual information in Web context or WCF context depending on some configuration parameters, I preferred to have similar idioms, and I wrote an HttpContext-like class for WCF.


///<summary>
/// This class incapsulates context information for a service instance
///</summary>
public class WcfInstanceContext : IExtension<InstanceContext>
{
    private readonly IDictionary items;

    private WcfInstanceContext()
    {
        items = new Hashtable();
    }

    ///<summary>
    /// <see cref="IDictionary"/> stored in current instance context.
    ///</summary>
    public IDictionary Items
    {
        get { return items; }
    }

    ///<summary>
    /// Gets the current instance of <see cref="WcfInstanceContext"/>
    ///</summary>
    public static WcfInstanceContext Current
    {
        get
        {
            WcfInstanceContext context = OperationContext.Current.InstanceContext.Extensions.Find<WcfInstanceContext>();
            if (context == null)
            {
                context = new WcfInstanceContext();
                OperationContext.Current.InstanceContext.Extensions.Add(context);
            }
            return context;
        }
    }

    /// <summary>
    /// <see cref="IExtension{T}"/> Attach() method
    /// </summary>
    public void Attach(InstanceContext owner) { }

    /// <summary>
    /// <see cref="IExtension{T}"/> Detach() method
    /// </summary>
    public void Detach(InstanceContext owner) { }
}
Now, you can use this class to store and retrieve data in the same manner as you’re working with HttpContext:
WcfInstanceContext.Current.Items["key"] = new MyClass();
MyClass myClass = WcfInstanceContext.Current.Items["key"] as MyClass;

3 comments:

Assil said...

That is an excellent smart way to solve a common desire..
Thank you!

Assil said...

What guarantees that
OperationContext.Current.InstanceContext != null
?

Unknown said...

Hi,

in ages when DI rules the world I would wrap it in some kind of service that could be easly injected in some common caching mechanisms (cache providers etc). But your solution seems to be nice for start.

Maćko