views:

345

answers:

1

Hi there,

Previously i managed to setup my unity to provide a new DataContext each time to my Repository project. It works great.

But for example, I am in a WCF method which opens up 2 services which in turn opens up 2 repositories (repository pattern).. i was hoping to be able to reuse the same datacontext within the same wcf method.

So i have been looking at RegisterInstance but i check the GetHashCode of the datacontext and its different each time. i thought unity will check the child container first every time which i presume i have an instance setup - see below

Here is my unity that executes once!

container.RegisterType<MyDataContext>(new TransientLifetimeManager(),
      new InjectionConstructor())

And then i try and configure in global.asax under Application_BeginRequest - but maybe this is not ideal as it seems to enter multiple times.. even when running the wcf service before someone calls a wcf method

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        Bootstrapper.ConfigureDataContextContainer();
    }

And here is my configureDataContextContainer

    public static void ConfigureDataContextContainer()
    {
        if (childContainer == null) // I have to do this otherwise it executes multiple times.
        {
            childContainer = Bootstrapper.Container.CreateChildContainer();
            childContainer.RegisterInstance<MyDataContext>
(container.Resolve<MyDataContext>());  // I Presume i create an instance here
        }
    }

As i say in my WCF method i am opening 2 services which in turn opens up "THEIR OWN" Respository which takes in a DataContext - MyDataContext

To fix the problem with the BeginRequest i could register the datacontext as an instance (if it worked :-) ) on every WCF method i have but it seems a bit of a long way round.

Of course its very imported that each connection (not sessions) gets its own DataContext.

I was disposing the datacontext when when i disposed of my repository ... now (if i can get it working) i presume i will need to dispose of this in EndRequest.. otherwise if one service completes and disposes of the DataContext and the other service hasn't finsihed then i am going to get issues.

I hope i have explained this well, :-)

Summary is that each WCF method must use its own datacontext , a web method can call more than 1 service (repository pattern) which in turn will call its repository which expects a datacontext on the constuctor which unity Registers - but currently when in the same WCF method, multiple services call there repositories and they get there own DataContext.

If i can clarify anything please let me know

Thanks

EDIT

Forgot to mention how i am getting unity to resolve things ... I simple call this on the container (not child container) to the service which in turn calls the respository

  using (IOfficeService officeService = Bootstrapper.Container.Resolve<IOfficeService >())
        {
+2  A: 

You are registering the instance in the child container, so you have to use the child container when resolving your service (Also, you should be disposing of your child container on Application_EndRequest):

using (var service = childContainer.Resolve<IOfficeService >())
{
}

However, using a PerRequestLifetimeManager should accomplish the same thing:

Container.RegisterType<MyDataContext>(new PerRequestLifetimeManager());

Here's how I implement it:

public class PerRequestLifetimeManager : LifetimeManager {
    private Guid key;

    public PerRequestLifetimeManager() {
        key = Guid.NewGuid();
    }

    public override object GetValue() {
        if (HttpContext.Current == null) {
            return null;
        } else {
            return HttpContext.Current.Items[key];
        }
    }

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

    public override void SetValue(object newValue) {
        if (HttpContext.Current != null) {
            HttpContext.Current.Items.Add(key, newValue);
        }
    }
}
Michael Valenty
Thank you Michael but the "PerRequestLifetimeManager" is going to give the same DataContext throughout - i.e. On every request that comes in? Hence different clients calling different wcf methods are all going to get the same DataContext?
mark smith
It means within a request the same instance will be returned. Essentially, each request will have it's own singleton. Different clients will not share the same instance.
Michael Valenty
Great, i was scratching my head at first as i couldn't find a perRequestLifeTimeManager .. but i managed to find one on the net... it works perfectly .. thanks.
mark smith
I edited my original answer to include my implementation of PerRequestLifetimeManager, I forgot that it was not included in Unity
Michael Valenty