You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Autofac的RegisterAssemblyTypes中按类名长度排序解决注入错误

解决Autofac服务类接口匹配错误的问题

问题背景

有两个以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();
        }
    }
}

你尝试通过OrderByDescending按类型名称长度排序来解决问题,但因RegisterAssemblyTypes返回的不是可枚举集合,导致编译报错:

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

解决方案

Autofac的RegisterAssemblyTypes返回的是IRegistrationBuilder而非可枚举集合,无法直接使用OrderByDescending。可以通过以下两种方式实现精准匹配:

方式一:先排序类型再逐个注册

先筛选出所有符合后缀条件的类型,按名称长度倒序排序后逐个注册,确保更长的类名优先匹配对应接口:

public class AutofacHelper
{
    public static void ScanAssembly(Assembly thisAssembly, ContainerBuilder builder)
    {
        var registerTypeStrings = GetRegisterTypeStrings();
        // 筛选所有符合后缀的类型并按名称长度倒序
        var targetTypes = thisAssembly.GetTypes()
                                      .Where(t => registerTypeStrings.Any(s => t.Name.EndsWith(s)))
                                      .OrderByDescending(t => t.Name.Length)
                                      .ToList();

        foreach (var type in targetTypes)
        {
            // 找到当前类型匹配的最长后缀,避免短后缀误匹配
            var matchedSuffix = registerTypeStrings.OrderByDescending(s => s.Length)
                                                   .First(s => type.Name.EndsWith(s));
            builder.RegisterType(type)
                   .AsImplementedInterfaces()
                   .SingleInstance();
        }
    }
}

方式二:先排序后缀列表再过滤注册

对registerTypeStrings按长度倒序排列,优先处理更长的后缀,同时过滤已匹配过长后缀的类型,避免重复注册:

public class AutofacHelper
{
    public static void ScanAssembly(Assembly thisAssembly, ContainerBuilder builder)
    {
        var registerTypeStrings = GetRegisterTypeStrings()
                                 .OrderByDescending(s => s.Length)
                                 .ToList();
        foreach (var item in registerTypeStrings)
        {
            builder.RegisterAssemblyTypes(thisAssembly)
                .Where(t => t.Name.EndsWith(item) 
                          // 排除已匹配更长后缀的类型
                          && !registerTypeStrings.Any(s => s.Length > item.Length && t.Name.EndsWith(s)))
                .AsImplementedInterfaces()
                .SingleInstance();
        }
    }
}

原理说明

两种方式核心逻辑一致:优先匹配更长的后缀或类名,确保CashregisterTurnoverGroupWebService不会被TurnoverGroupWebService的短后缀规则误匹配,从而正确关联到IReadCashregisterTurnoverGroupWebService接口。

内容的提问来源于stack exchange,提问作者J. Rahmati

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 06:41:00