如何让AutoMapper通过Autofac自动解析实例?集成问题求助
AutoMapper + Autofac 自动解析实例的最优实现
绝对可以实现AutoMapper自动通过Autofac解析目标实例,不用每次手动写ConstructUsing,咱们来梳理正确的做法,顺便解决你之前遇到的问题。
先说说你之前代码的问题
- 你第一次修改时在
MapperConfiguration的lambda里直接调用c.Resolve<IEnumerable<Profile>>(),这时候Autofac容器还没完成构建,直接解析会触发异常(也就是你遇到的“重复使用已定义的builder”相关问题)。 - 直接依赖
CSContainer.Instance这种静态容器实例是不好的实践,会破坏依赖注入的生命周期管理,比如无法使用子作用域处理请求级别的对象。 - 第二次修改里的
scope.Resolve没有正确和AutoMapper的构造服务逻辑绑定,导致AutoMapper还是无法正确通过Autofac解析目标实例。
最优实现代码
下面是正确的Autofac Module配置,核心是让AutoMapper完全依托Autofac的生命周期来构造服务和目标对象:
public class AutoMapperModule : Module { protected override void Load(ContainerBuilder builder) { base.Load(builder); // 1. 扫描并注册所有程序集里的AutoMapper Profile var assemblies = AppDomain.CurrentDomain.GetAssemblies(); builder.RegisterAssemblyTypes(assemblies) .Where(t => typeof(Profile).IsAssignableFrom(t) && !t.IsAbstract && t.IsPublic) .As<Profile>(); // 2. 配置MapperConfiguration,让它使用Autofac来构造所需服务 builder.Register(c => new MapperConfiguration(cfg => { // 关键:告诉AutoMapper用Autofac的解析器来构造所有需要的服务(包括目标实例) cfg.ConstructServicesUsing(type => c.Resolve(type)); // 加载所有注册的Profile foreach (var profile in c.Resolve<IEnumerable<Profile>>()) { cfg.AddProfile(profile); } })) .AsSelf() .AutoActivate() .SingleInstance(); // 3. 注册IMapper,确保它使用Autofac的解析逻辑 builder.Register(c => c.Resolve<MapperConfiguration>().CreateMapper(c.Resolve)) .As<IMapper>() .SingleInstance(); } }
关键说明
ConstructServicesUsing的作用:这个方法告诉AutoMapper,当它需要创建任何类型的实例(包括目标对象、自定义值解析器、类型转换器等)时,都通过Autofac的Resolve方法来获取,而不是用默认的无参构造函数。- 避免静态容器依赖:全程使用Autofac提供的
IComponentContext(也就是代码里的c参数)来解析对象,不要用CSContainer.Instance这种静态实例,确保生命周期管理正确。 - Profile的注册:扫描程序集自动注册Profile,避免手动一个个添加,保持代码模块化。
验证自动解析的步骤
- 先把你的目标类型注册到Autofac,比如:
// 假设你的目标类Destination有带参数的构造函数,参数已经注册到Autofac builder.RegisterType<Destination>().AsSelf(); builder.RegisterType<SomeDependency>().As<ISomeDependency>();
- 在Profile里定义映射,不需要写
ConstructUsing:
public class MyProfile : Profile { public MyProfile() { CreateMap<Source, Destination>(); } }
- 当你调用
IMapper.Map<Destination>(source)时,AutoMapper会自动通过Autofac解析Destination的实例,不需要手动指定构造逻辑。
为什么之前的异常会出现?
你之前遇到的“要创建的对象需无参或仅含可选参数”异常,是因为AutoMapper没有正确拿到Autofac的解析器,只能尝试用默认的无参构造函数创建目标对象,但你的目标类没有无参构造函数,所以报错。上面的配置通过ConstructServicesUsing把Autofac的解析能力注入给AutoMapper,就能解决这个问题。
内容的提问来源于stack exchange,提问作者user4266661
相关产品推荐
相关产品推荐

