如何在 ContainerBuilder.RegisterAssemblyTypes 上使用 orderby?

问题描述 投票:0回答:2

我有 2 个服务类别,均以 Service 结尾: TurnoverGroupWebService 和 CashregisterTurnoverGroupWebService。

这两个类本来应该自动注册为

IReadTurnoverGroupWebService
&
IReadCashregisterTurnoverGroupWebService
,但是因为两者都以
TurnoverGroupWebService
结尾,所以错误的接口注入到了
CashregisterTurnoverGroupWebService

这是一些进行注册的代码:

public class AutofacHelper
{
    public static void ScanAssembly(Assembly thisAssembly, ContainerBuilder builder)
    {
        var registerTypeStrings = GetRegisterTypeStrings();
        foreach (var item in registerTypeStrings)
        {
            builder.RegisterAssemblyTypes(thisAssembly)
                .Where(t => t.Name.EndsWith(item))
                .AsImplementedInterfaces()
                .SingleInstance();
        }
    }
}

有没有办法按字符串长度对类型进行排序,以便将

CashregisterTurnoverGroupWebService
注册为
IReadCashregisterTurnoverGroupWebService
而不是
TurnoverGroupWebService

我尝试在

OrderBy
之后添加
RegisterAssemblyTypes
,但出现编译错误,因为
RegisterAssemblyTypes
不返回列表:

builder.RegisterAssemblyTypes(thisAssembly)
                .OrderByDescending(t => t.Name.Length)
                .Where(t => t.Name.EndsWith(item))
                .AsImplementedInterfaces()
                .SingleInstance();
c# dependency-injection autofac
2个回答
0
投票

按名称结尾过滤类型后,您可以使用 OrderByDescending 方法来实现注册顺序。要解决您提到的编译错误,您可以首先过滤类型,然后使用 OrderByDescending 方法按名称长度对它们进行排序。

以下是修改代码的方法:

        builder.RegisterAssemblyTypes(thisAssembly)
            .Where(t => t.Name.EndsWith(item))
            .OrderByDescending(t => t.Name.Length)
            .AsImplementedInterfaces()
            .SingleInstance();
    

0
投票

正如您所见,这并不是装配体扫描的真正工作原理。它比获取类型列表和过滤要复杂得多。您可以在此处查看来源。简短版本:当您这样做时,它实际上并没有像普通

builder.RegisterType<T>
那样创建单独的注册。

如果您需要控制注册顺序,我建议您选择以下两件事之一,这两者都意味着使用

RegisterAssemblyTypes

选项 1:模块

不要扫描一堆程序集中的每种类型,而是按所需顺序将所需的特定类型放入模块中,然后注册该模块。是的,这意味着您不会“动态扫描”每种类型,但听起来您已经需要了解太多内容而无法仅仅进行扫描。 选项 2:自己枚举类型

不要告诉 Autofac 扫描类型,而是

这样做。 var assemblies = GetTheAssembliesYouWant(); // GetLoadableTypes is an extension in Autofac.Util.AssemblyExtensions // that helps filter out types that might have missing dependencies // or other issues that would cause problems. var types = assemblies .SelectMany(asm => asm.GetLoadableTypes()) .Where(t => t.HasThePropertyYouWant()) .OrderBy(t => t.WhateverYourSortIs()); foreach (var type in types) { // Configure this however you want. builder.RegisterType(type).AsImplementedInterfaces(); }

重点是您需要直接控制注册过程,而不是依赖 Autofac。

如果是我,我会选择模块。我从来都不是
RegisterAssemblyTypes

的粉丝,因为它会导致各种各样的问题,人们没有意识到一些额外的类型潜入了,或者出现了一些排序问题(像这样),或者其他什么。控制注册并明确。以后排除故障和弄清楚会更容易,而且不会出现意外。

但我知道注册程序集类型和扫描是

容易

,所以这就是权衡。

© www.soinside.com 2019 - 2024. All rights reserved.