views:

1975

answers:

1

I have a unity container and use RegisterType to register the following repository and implementer using ContainerControlledLifetimeManager.

public interface IPersonRepository
{
  Person GetByID(ObjectSpace objectSpace, int id);
}

Using this pattern I am able to have multiple threads (it's a web app) using the same repository instance at the same time despite the fact that each thread is using a different ObjectSpace (which is a local cache + mechanism for fetching objects from the DB + a unit of work etc). But this makes me feel "dirty", and not the good kind :-)

What I would really like is

public interface IPersonRepository
{
  Person GetByID(int id);
}

To achieve this I would have to create a child container and use RegisterInstance to register my ObjectSpace. This would work fine as long as I either

  1. Register IPersonRepository in the child container instead
  2. Change the lifetime manager to TransientLifetimeManager

I don't want to do either. (1) Would just be too much work, I want to register once in the parent container and then no more. (2) Would work but if there are a lot of dependencies then all of these would have to be transient too and this would result in a lot of instances being created every time I needed the person repository.

So my question is. Is there a way to register the type in the parent, but to have a container lifetime instance resolved and stored in the child container instead of the parent container? Maybe there is a way using a custom lifetime manager or something?

What I would like to achieve is this

UnityContainer unityContainer = new UnityContainer();
//Might be a custom manager or something
unityContainer.RegisterType<IPersonRepository, PersonRepository>
  (new ContainerControlledLifetimeManager()); 
using (var childContainer = unityContainer.CreateChildContainer())
{
    childContainer.RegisterInstance<ObjectSpace>(new MyObjectSpace());
    //01 Resolves a new instance inside the child container
    var repository = childContainer.Resolve<IPersonRepository>();
    //02 resolves same instance as 01
    repository = childContainer.Resolve<IPersonRepository>();
}

using (var childContainer = unityContainer.CreateChildContainer())
{
    childContainer.RegisterInstance<ObjectSpace>(new MyObjectSpace());
    //03 Resolves a new instance inside the child container
    var repository = childContainer.Resolve<IPersonRepository>();
    //04 resolves same instance as 03
    repository = childContainer.Resolve<IPersonRepository>(); //Resolves the same instance
}