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
- Register IPersonRepository in the child container instead
- 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
}