AutoMapper泛型TypeConverter是否需要在DI容器中注册?
问题场景
在WebApi项目中配置了AutoMapper泛型映射:
cfg.CreateMap(typeof(Source<>), typeof(Destination), MemberList.Destination) .ConvertUsing(typeof(SourceConverter<>));
对应的泛型转换器实现:
internal class SourceConverter<T> : ITypeConverter<Source<T>, Destination> where T : struct, IConvertible { public Destination Convert(SourceConverter<T> exception, Destination error, ResolutionContext ctx) { return new Destination(); } }
执行映射操作时抛出以下异常:
The requested service 'SourceConverter`1[[MyEnum, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.
问题:此类泛型TypeConverter是否需要在依赖注入(DI)容器中进行注册?
回答
需要注册,而且必须注册开放泛型类型的转换器,不能只注册某个具体的封闭泛型版本。
原因很明确:当你在AutoMapper中通过ConvertUsing(typeof(SourceConverter<>))指定开放泛型转换器时,AutoMapper会在执行映射时,根据实际的泛型参数(比如MyEnum)生成对应的封闭泛型实例(SourceConverter<MyEnum>),并尝试从DI容器中获取这个实例。如果DI容器里没注册开放泛型的SourceConverter<>,就会触发你看到的未注册异常。
注册示例(ASP.NET Core DI环境)
services.AddScoped(typeof(SourceConverter<>));
另外注意你的转换器Convert方法参数存在错误:按照ITypeConverter<TSource, TDestination>接口的定义,第一个参数应该是Source<T>类型(即源对象),而不是SourceConverter<T>,修正后才能符合接口规范:
public Destination Convert(Source<T> source, Destination destination, ResolutionContext ctx) { // 编写实际的转换逻辑 return new Destination(); }
内容的提问来源于stack exchange,提问作者Ivan-Mark Debono

