Unity Container: как зарегистрировать и разрешить множество реализаций по пространству имен? - PullRequest
0 голосов
/ 25 января 2019

Context .Предположим, что у нас есть следующая IDocument иерархия и IFunctionary, ответственность за которую должна обрабатывать IDocument s.

interface IDocument { }
interface IOrder : IDocument { }
interface IBill : IDocument { }

interface IFunctionary<TDoc> where TDoc : IDocument { 
    void Treat(TDoc document); 
}

Также есть другое ветвление: предположим, у нас есть две фазы обработки документов, описываемые классами DocumentPreparation и DocumentAcceptance.

class DocumentPreparation {
    public DocumentPreparation(
        IFunctionary<IOrder>[] orderFunctionaries,
        IFunctionary<IBill>[] billFunctionaries
    ) { }
}

class DocumentAcceptance {
    public DocumentAcceptance(
        IFunctionary<IOrder>[] orderFunctionaries,
        IFunctionary<IBill>[] billFunctionaries
    ) { }
}

Намерение .Я хотел бы предоставить все реализации IFunctionary<TDoc> из пространства имен Preparation в DocumentPreparation и все реализации IFunctionary<TDoc> из пространства имен Acceptance в DocumentAcceptance.

Вопрос ,Как мне настроить Unity Container , чтобы добиться этого?

Что я пробовал .Я могу получить все необходимые типы и зарегистрировать их под разными именами или с одинаковыми именами.Но код unity.Resolve<IFunctionary<IOrder>[]>("Preparation") возвращает все реализации IFunctionary<IOrder> независимо от имен, с которыми они были зарегистрированы.Таким образом, кажется невозможным использовать простые именованные регистрации для разделения реализаций по группам.

1 Ответ

0 голосов
/ 30 января 2019

Наконец, мы пришли к следующему решению.

Сначала регистрируются все реализации (из обоих пространств имен) интерфейса IFunctionary<TDoc> с помощью метода UnityContainerRegistrationByConventionExtensions.RegisterTypes.

После этогорегистрирует классы DocumentPreparation и DocumentAcceptance, используя что-то вроде следующего кода.

container.RegisterType<DocumentPreparation , DocumentPreparation>(
    new HierarchicalLifetimeManager(),
    new InjectionFactory(c => new DocumentPreparation(
        c.ResolveAll<IFunctionary<IOrder>>()
            .Where(f => {
                var typeNamespace = f.GetType().Namespace;
                return typeNamespace != null && typeNamespace == "Preparation";
            }).ToArray(),
        c.ResolveAll<IFunctionary<IBill>>()
            .Where(f => {
                var typeNamespace = f.GetType().Namespace;
                return typeNamespace != null && typeNamespace == "Preparation";
            }).ToArray())
        ));

Этот фрагмент кода должен быть продублирован для класса DocumentAcceptance.

Это решение имеет очевидные преимуществаи недостатки.

...