Как зарегистрировать сопоставление именованного типа для разрешения сопоставления безымянного типа - PullRequest
0 голосов
/ 02 сентября 2011

Я использую сущностный каркас с шаблоном проектирования рабочих единиц, моя структура классов выглядит следующим образом:

public interface IUnitOfWork
{
    void Save();
}

public class MyContext : ObjectContext, IUnitOfWork
{
    public void Save()
    {
        SaveChanges();
    }
}

Затем я регистрирую отображение типа MyContext как:

IUnityContainer unityContainer = new UnityContainer()
    .RegisterType<MyContext>(new ContainerControlledLifetimeManager());

Я знаю, если бы я сделал следующее:

unityContainer.RegisterType<IUnitOfWork, MyContext>();
IUnitOfWork unitOfWork1 = unityContainer.Resolve<IUnitOfWork>();
IUnitOfWork unitOfWork2 = unityContainer.Resolve<IUnitOfWork>();

Тогда unitOfWork1 будет тем же MyContext экземпляром, что и unitOfWork2, так как IUnitOfWork сопоставляется с MyContext, который является контролируемым контейнером экземпляром..

Однако, если вместо этого я сделаю это:

unityContainer.RegisterType<IUnitOfWork, MyContext>("MyUnitOfWork");
IUnitOfWork unitOfWork1 = unityContainer.Resolve<IUnitOfWork>("MyUnitOfWork");
IUnitOfWork unitOfWork2 = unityContainer.Resolve<IUnitOfWork>("MyUnitOfWork");

Тогда unitOfWork1 и unitOfWork2 разрешат два разных экземпляра MyContext, что не имеет никакого смысла дляменя, так как они оба сопоставляются с MyContext, который все еще является экземпляром, управляемым контейнером.Похоже, что когда имена сопоставляются, они не разрешают параметр второго типа одинаково.

Причина, по которой мне требуются сопоставления именованных типов, заключается в том, что у меня есть несколько различных ObjectContext, которые все реализуютIUnitOfWork, поэтому было бы неправильно определять глобальное IUnitOfWork отображение типов.

У меня простой вопрос: как я могу использовать именованные отображения типов, но при этом сохранить функциональность первой реализации.

NB Я на самом деле использую PerResolveLifetimeManager в своей реальной реализации, однако ContainerControlledLifetimeManager выделяет смысл в меньшем количестве кода.

Редактировать
Согласно моему разговору с ДэниеломХильгарт.

Я исправил свою проблему, изменив регистрацию класса со свойством зависимости IUnitOfWork.

Раньше это было следующим образом:

unityContainer.RegisterType<Service>(new InjectionConstructor(new ResolvedParameter<IUnitOfWork>("MyUnitOfWork")));

Однако вместо разрешения именованного IUnitOfWork я выбрал другой подход и вместо этого непосредственно разрешил реализацию:

unityContainer.RegisterType<Service>(new InjectionConstructor(new ResolvedParameter<MyContext>()));

Спасибо Дэниелу и TheCodeKing за объяснениег цель именованных регистраций:)

Ответы [ 2 ]

1 голос
/ 02 сентября 2011

В ContainerControlledLifetimeManager применяется одиночка, поэтому вы всегда получаете один и тот же экземпляр.Чтобы использовать именованные экземпляры, которые разрешают одиночный код, вам нужно.

unityContainer.RegisterType<IUnitOfWork, MyContext>
                     ("MyUnitOfWork", new ContainerControlledLifetimeManager());
IUnitOfWork unitOfWork1 = unityContainer.Resolve<IUnitOfWork>("MyUnitOfWork");
IUnitOfWork unitOfWork2 = unityContainer.Resolve<IUnitOfWork>("MyUnitOfWork");
1 голос
/ 02 сентября 2011

Просто передайте пожизненный менеджер:

unityContainer.RegisterType<IUnitOfWork, MyContext>(
    "MyUnitOfWork", new ContainerControlledLifetimeManager());

Причина:
Вы зарегистрировали безымянный экземпляр MyContext как экземпляр, управляемый контейнером, а не с именем one.

...