Как зарегистрировать типы в основном контейнере, но разрешить в дочернем контейнере? - PullRequest
4 голосов
/ 10 февраля 2009

У меня есть единичный контейнер, и я использую RegisterType, чтобы зарегистрировать следующий репозиторий и реализатор, используя ContainerControlledLifetimeManager.

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

Используя этот шаблон, я могу иметь несколько потоков (это веб-приложение), использующих один и тот же экземпляр хранилища в одно и то же время, несмотря на тот факт, что каждый поток использует различный ObjectSpace (который является механизмом локального кэша + для выборка объектов из БД + единица работы и т. д.). Но это заставляет меня чувствовать себя "грязным", а не хорошим видом: -)

Что бы я действительно хотел:

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

Для этого мне нужно создать дочерний контейнер и использовать RegisterInstance, чтобы зарегистрировать мой ObjectSpace. Это будет работать нормально, если я тоже:

  1. Зарегистрируйте IPersonRepository в дочернем контейнере вместо
  2. Измените менеджер времени жизни на 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
}

1 Ответ

1 голос
/ 18 января 2016

Поскольку после задания вопроса в Unity был добавлен новый HierarchicalLifetimeManager, его следует использовать при регистрации типа.

...