Autofac如何动态注册带泛型的具体类型与对应泛型接口
Autofac动态注册开放泛型类型解决方案
常规的RegisterAssemblyTypes方法无法满足你的需求,因为它默认注册的是封闭泛型类型(例如Foo<int>),而你需要注册开放泛型定义(例如Foo<>),这样Autofac才能在解析IFoo<MyGenericType>时自动生成对应封闭类型的实例。
你可以通过以下代码实现动态注册:
- 筛选程序集中符合条件的开放泛型具体类
var assemblies = /* 替换为你的目标程序集集合 */; var openGenericConcreteTypes = assemblies .SelectMany(assembly => assembly.GetTypes()) .Where(type => type.IsGenericTypeDefinition && // 是开放泛型定义(如Foo<>) !type.IsAbstract && // 非抽象类 type.GetConstructors().Any(ctor => ctor.IsPublic) // 包含公共构造函数 );
- 遍历筛选后的类型,匹配对应的开放泛型接口并注册
foreach (var concreteType in openGenericConcreteTypes) { // 获取当前类实现的所有匹配开放泛型接口 var matchingOpenInterfaces = concreteType.GetInterfaces() .Where(@interface => @interface.IsGenericTypeDefinition && // 确保接口与类的泛型参数数量一致 @interface.GetGenericArguments().Length == concreteType.GetGenericArguments().Length && // 验证类确实是该接口的实现(通过构造临时封闭类型验证) concreteType.MakeGenericType(typeof(object)).GetInterfaces() .Contains(@interface.MakeGenericType(typeof(object))) ); foreach (var interfaceType in matchingOpenInterfaces) { containerBuilder.RegisterGeneric(concreteType).As(interfaceType); } }
关键说明
- 这段代码会自动识别每个开放泛型类对应的专属开放泛型接口,效果与你手动写
RegisterGeneric(typeof(Foo<>)).As(typeof(IFoo<>))完全一致 - 如果一个类实现了多个符合条件的开放泛型接口,代码会自动全部注册
- 确保你的泛型类和对应接口的泛型参数数量、约束匹配,避免注册失败
内容的提问来源于stack exchange,提问作者Ian Jones
相关产品推荐
相关产品推荐

