我有 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();
按名称结尾过滤类型后,您可以使用 OrderByDescending 方法来实现注册顺序。要解决您提到的编译错误,您可以首先过滤类型,然后使用 OrderByDescending 方法按名称长度对它们进行排序。
以下是修改代码的方法:
builder.RegisterAssemblyTypes(thisAssembly)
.Where(t => t.Name.EndsWith(item))
.OrderByDescending(t => t.Name.Length)
.AsImplementedInterfaces()
.SingleInstance();
正如您所见,这并不是装配体扫描的真正工作原理。它比获取类型列表和过滤要复杂得多。您可以在此处查看来源。简短版本:当您这样做时,它实际上并没有像普通
builder.RegisterType<T>
那样创建单独的注册。
如果您需要控制注册顺序,我建议您选择以下两件事之一,这两者都意味着不使用
RegisterAssemblyTypes
。
不要扫描一堆程序集中的每种类型,而是按所需顺序将所需的特定类型放入模块中,然后注册该模块。是的,这意味着您不会“动态扫描”每种类型,但听起来您已经需要了解太多内容而无法仅仅进行扫描。 选项 2:自己枚举类型
这样做。
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
的粉丝,因为它会导致各种各样的问题,人们没有意识到一些额外的类型潜入了,或者出现了一些排序问题(像这样),或者其他什么。控制注册并明确。以后排除故障和弄清楚会更容易,而且不会出现意外。
但我知道注册程序集类型和扫描是容易,所以这就是权衡。