如何使用Unity动态注册AutoMapper的IValueResolver接口多个实现
解决AutoMapper IValueResolver多实现的Unity DI注册问题
我之前也碰到过类似的场景,结合你已经有的动态扫描Profile和Unity集成逻辑,给你梳理几个实用的解决方案,重点解决多个IValueResolver实现的注册与使用问题:
核心前提:让AutoMapper依赖Unity解析服务
首先你已经提到的关键步骤不能少——初始化AutoMapper时必须指定用Unity来构造服务,这样所有需要注入依赖的IValueResolver才能被正确实例化:
var mapperConfig = new MapperConfiguration(cfg => { // 你的动态扫描Profile逻辑 var profileTypes = Assembly.GetExecutingAssembly() .GetTypes() .Where(t => typeof(Profile).IsAssignableFrom(t) && !t.IsAbstract); foreach (var type in profileTypes) { cfg.AddProfile(Activator.CreateInstance(type) as Profile); } // 关键:把Unity容器传给AutoMapper作为服务构造器 cfg.ConstructServicesUsing(type => container.Resolve(type)); }); // 将IMapper实例注册到Unity container.RegisterInstance<IMapper>(mapperConfig.CreateMapper());
场景1:按命名区分多个Resolver实现
如果不同的IValueResolver对应不同的映射场景(比如用户模型转换和订单模型转换用不同的Resolver),可以给每个Resolver注册命名实例,然后在Profile中指定使用对应名称的实例:
步骤1:Unity中注册命名Resolver
// 给每个Resolver指定唯一名称 container.RegisterType<IValueResolver, UserToDtoResolver>("UserMappingResolver"); container.RegisterType<IValueResolver, OrderToDtoResolver>("OrderMappingResolver");
步骤2:Profile中指定命名Resolver
在映射配置里通过名称定位到对应的Resolver:
public class AppMappingProfile : Profile { public AppMappingProfile() { CreateMap<User, UserDto>() .ForMember(dest => dest.FullName, opt => opt.MapFrom<IValueResolver>("UserMappingResolver")); CreateMap<Order, OrderDto>() .ForMember(dest => dest.TotalAmount, opt => opt.MapFrom<IValueResolver>("OrderMappingResolver")); } }
场景2:直接注册具体Resolver类型(更直观)
如果每个IValueResolver都是针对特定映射逻辑的专属实现,不需要共享接口的多实例,可以直接注册具体类型,在Profile中直接指定该类型:
步骤1:Unity中注册具体Resolver类
// 直接注册具体Resolver,Unity会自动处理其构造函数依赖 container.RegisterType<UserToDtoResolver>(); container.RegisterType<OrderToDtoResolver>();
步骤2:Profile中直接指定Resolver类型
这种方式更清晰,也避免了命名冲突问题:
public class AppMappingProfile : Profile { public AppMappingProfile() { CreateMap<User, UserDto>() .ForMember(dest => dest.FullName, opt => opt.MapFrom<UserToDtoResolver>()); CreateMap<Order, OrderDto>() .ForMember(dest => dest.TotalAmount, opt => opt.MapFrom<OrderToDtoResolver>()); } }
结合动态扫描的注意事项
你现有的动态扫描Profile逻辑不需要做任何修改——只要确保所有IValueResolver实现都已经在Unity中注册完成,AutoMapper在解析时会自动通过Unity获取对应的实例,不管是命名实例还是具体类型。
另外要注意:如果你的IValueResolver有构造函数依赖(比如你提到的资源依赖),只要这些依赖已经在Unity中注册,Unity会自动注入给Resolver实例。
内容的提问来源于stack exchange,提问作者Keith
相关产品推荐
相关产品推荐

