У меня есть единичный контейнер, и я использую RegisterType
, чтобы зарегистрировать следующий репозиторий и реализатор, используя ContainerControlledLifetimeManager
.
public interface IPersonRepository
{
Person GetByID(ObjectSpace objectSpace, int id);
}
Используя этот шаблон, я могу иметь несколько потоков (это веб-приложение), использующих один и тот же экземпляр хранилища в одно и то же время, несмотря на тот факт, что каждый поток использует различный ObjectSpace
(который является механизмом локального кэша + для выборка объектов из БД + единица работы и т. д.). Но это заставляет меня чувствовать себя "грязным", а не хорошим видом: -)
Что бы я действительно хотел:
public interface IPersonRepository
{
Person GetByID(int id);
}
Для этого мне нужно создать дочерний контейнер и использовать RegisterInstance
, чтобы зарегистрировать мой ObjectSpace
. Это будет работать нормально, если я тоже:
- Зарегистрируйте
IPersonRepository
в дочернем контейнере вместо
- Измените менеджер времени жизни на
TransientLifetimeManager
Я тоже не хочу этого делать. (1) Было бы просто слишком много работы, я хочу зарегистрироваться один раз в родительском контейнере, а затем не более. (2) Работало бы, но если бы было много зависимостей, то все они тоже должны были бы быть временными, и это приводило бы к тому, что каждый раз, когда мне понадобился репозиторий, создавалось множество экземпляров.
Итак, мой вопрос: есть ли способ зарегистрировать тип в родительском объекте, но чтобы разрешить экземпляр времени жизни контейнера и сохранить его в дочернем контейнере вместо родительского контейнера? Может быть, есть какой-нибудь способ использовать собственный менеджер времени жизни или что-то в этом роде?
Чего я хотел бы достичь, так это:
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
}