Я использую сущностный каркас с шаблоном проектирования рабочих единиц, моя структура классов выглядит следующим образом:
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 за объяснениег цель именованных регистраций:)