Я преобразую Prim 6, используя MEF для IOC, в Prism 7 Unity, поскольку MEF больше не поддерживается.Самым большим отличием, с которым мне приходится бороться, является предположение в MEF, что по умолчанию все одноэлементно, в то время как Unity имеет тенденцию предполагать обратное.
У меня большая часть преобразована, но я столкнулся с одной ссылкой на конструкторсинглтон через коллекции.Например, у меня есть следующие интерфейсы и классы:
public interface IAppService { }
public interface IDebugService : IAppService { }
public class DebugService : IDebugService { }
public interface IOtherService : IAppService { }
public class OtherService : IOtherService { }
с DebugService
и OtherService
регистрируется как синглтоны и отображается на оба их соответствующих интерфейса:
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterSingleton<IModuleMessageBus, ModuleMessageBus>();
containerRegistry.RegisterSingleton<DebugService>();
containerRegistry.RegisterSingleton<IDebugService, DebugService>();
containerRegistry.Register<IAppService, DebugService>(typeof(DebugService).FullName);
containerRegistry.RegisterSingleton<OtherService>();
containerRegistry.RegisterSingleton<IOtherService, OtherService>();
containerRegistry.Register<IAppService, OtherService>(typeof(OtherService).FullName);
}
Цельis DebugService
/ IDebugService
и OtherService
/ IOtherService
зарегистрированы / сопоставлены как синглтоны, которые возвращают один и тот же экземпляр, но IAppService
как именованные экземпляры каждого, так что может быть зарегистрировано более одного IAppService
.Любой звонок для получения коллекции будет включать в себя синглтон DebugService
и OtherService
.
Вторая часть - это то, что вызывает у меня проблему.Получение коллекции IAppService
в конструкторе всегда генерирует новые экземпляры.Итак, если у меня есть это:
public SomeViewModel(
IModuleMessageBus messageBus
, IDebugService debugService
, IEnumerable<IAppService> services
) { }
public AnotherViewModel(
IModuleMessageBus messageBus
, IDebugService debugService
) { }
Что произойдет, если конструктор для DebugService
получит двойной удар.Один раз для IDebugService
инъекции для ОБА конструкторов и еще раз специально для IEnumerable
.Если я закомментирую , IEnumerable<IAppService> services
, то это будет только один раз.Как я могу иметь один и только один экземпляр сервисов, но при этом регистрировать их с другими интерфейсами для получения в виде коллекций.
ОБНОВЛЕНИЕ
Благодаря ответу ХокингераЯ взглянул на github Prism, так как эта перегрузка не отображается модулем.Оказывается, они добавляют это в 7.2.Последний предварительный просмотр (5 дней на момент написания этой статьи) содержит:
https://github.com/PrismLibrary/Prism/pull/1668
ОБНОВЛЕНИЕ 2
К сожалению, это все еще кажется проблемой.Я изменил регистрацию на эту, и она все еще используется дважды:
containerRegistry.RegisterSingleton<DebugService>();
containerRegistry.RegisterSingleton<IDebugService, DebugService>();
containerRegistry.GetContainer().RegisterSingleton(
typeof(IAppService)
, typeof(DebugService)
, typeof(DebugService).FullName
);
containerRegistry.RegisterSingleton<OtherService>();
containerRegistry.RegisterSingleton<IOtherService, OtherService>();
containerRegistry.GetContainer().RegisterSingleton(
typeof(IAppService)
, typeof(OtherService)
, typeof(OtherService).FullName
);
Обновление PRISM до предварительного просмотра не будет иметь значения, так как оно все еще ссылается на те же версии единства.Но обновление пакетов Unity сломает Prism, так как они содержат изменения торможения (похоже на Unity.Abstraction).
ОТВЕТИТЬ СПАСИБО HAUKINGER
Haukinger поставил меняна правильном пути, так что дайте ему толчок, если это поможет !!
Поскольку призма 7 (в настоящее время) использует Unit Container 5.8 / Unity Abstraction 3, мы должны использовать InjectionFactory
, который помечен как устаревший искоро будет удален.Чтобы заставить вышеописанное работать, я должен был сделать это (тааак брутто):
containerRegistry.RegisterSingleton<DebugService>();
containerRegistry.RegisterSingleton<IDebugService, DebugService>();
//Manually map the registration resolve
containerRegistry.GetContainer().RegisterType<IAppService>(
typeof(DebugService).FullName
, new InjectionFactory(c => c.Resolve<DebugService>())
);
containerRegistry.RegisterSingleton<OtherService>();
containerRegistry.RegisterSingleton<IOtherService, OtherService>();
//Manually map the registration resolve
containerRegistry.GetContainer().RegisterType<IAppService>(
typeof(OtherService).FullName
, new InjectionFactory(c => c.Resolve<OtherService>())
);