Peter Morris Peter Morris - 1 month ago 5
C# Question

How to register types in the main container, but resolve in a child container?

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
}

Answer

Since asking the question a new HierarchicalLifetimeManager has been added to Unity, this should be used when registering the type.