简体   繁体   English

Unity Container:如何通过命名空间注册和解析许多实现?

[英]Unity Container: how to register and resolve many implementations by namespace?

Context .上下文 Suppose we have the following IDocument hierarchy and IFunctionary which responsibility is to treat IDocument s.假设我们有以下IDocument层次结构和IFunctionary ,其职责是处理IDocument

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

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

Also there is another branching: suppose we have two phases of document treating described by classes DocumentPreparation and DocumentAcceptance .还有另一个分支:假设我们有两个阶段的文档处理,由类DocumentPreparationDocumentAcceptance描述。

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

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

Intention .意图 I would like to supply all implementations of IFunctionary<TDoc> from namespace Preparation to DocumentPreparation and all implementations of IFunctionary<TDoc> from namespace Acceptance to DocumentAcceptance .我想提供的所有实现IFunctionary<TDoc>从名称空间PreparationDocumentPreparation和的所有实现IFunctionary<TDoc>从名称空间AcceptanceDocumentAcceptance

Question .问题 How should I tune the Unity Container to achieve that?我应该如何调整Unity Container以实现这一目标?

What have I tried .我试过什么了 I can retrieve all necessary types and register them with different names or with the same names.我可以检索所有必需的类型并使用不同的名称或相同的名称注册它们。 But the code unity.Resolve<IFunctionary<IOrder>[]>("Preparation") returns all implementations of IFunctionary<IOrder> regardless of names they have been registered with.但是代码unity.Resolve<IFunctionary<IOrder>[]>("Preparation")返回IFunctionary<IOrder>所有实现,无论它们已注册的名称如何。 Thus it seems impossible to use simple named registrations to divide implementations in groups.因此,似乎不可能使用简单的命名注册将实现分组。

Finally we have came to the following solution.最后我们得出了以下解决方案。

At first one registers all implementations (from both namespaces) of the IFunctionary<TDoc> interface via UnityContainerRegistrationByConventionExtensions.RegisterTypes method.首先,通过UnityContainerRegistrationByConventionExtensions.RegisterTypes方法注册IFunctionary<TDoc>接口的所有实现(来自两个命名空间)。

After that one registers both DocumentPreparation and DocumentAcceptance classes using something like the following code.之后,使用类似于以下代码的内容注册DocumentPreparationDocumentAcceptance类。

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())
        ));

This code snippet should be duplicated for the DocumentAcceptance class.应为DocumentAcceptance类复制此代码片段。

This solution contains obvious advantages and drawbacks.该解决方案包含明显的优点和缺点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM