ABP AutoMapper
ABP AutoMapper
2023/6/1
➡️

auto mapper

社区开源库 AutoMapper 提供的映射核心代码 IMapperBase-->IMapper-->Mapper

namespace AutoMapper;

public interface IMapperBase
{
  TDestination Map<TDestination>(object source);
  TDestination Map<TSource, TDestination>(TSource source);
  TDestination Map<TSource, TDestination>(TSource source, TDestination destination);
  object Map(object source, Type sourceType, Type destinationType);
  object Map(object source, object destination, Type sourceType, Type destinationType);
}

public interface IMapper : IMapperBase
{

  TDestination Map<TDestination>(

    object source,
    Action<IMappingOperationOptions<object, TDestination>> opts);

  TDestination Map<TSource, TDestination>(

    TSource source,
    Action<IMappingOperationOptions<TSource, TDestination>> opts);

  TDestination Map<TSource, TDestination>(

    TSource source,
    TDestination destination,
    Action<IMappingOperationOptions<TSource, TDestination>> opts);

  object Map(

    object source,
    Type sourceType,
    Type destinationType,
    Action<IMappingOperationOptions<object, object>> opts);

  object Map(

    object source,
    object destination,
    Type sourceType,
    Type destinationType,
    Action<IMappingOperationOptions<object, object>> opts);

  IQueryable<TDestination> ProjectTo<TDestination>(

    IQueryable source,
    object parameters = null,
    params Expression<Func<TDestination, object>>[] membersToExpand);

  IQueryable<TDestination> ProjectTo<TDestination>(

    IQueryable source,
    IDictionary<string, object> parameters,
    params string[] membersToExpand);

  IQueryable ProjectTo(

    IQueryable source,
    Type destinationType,
    IDictionary<string, object> parameters = null,
    params string[] membersToExpand);

}

实现类

namespace AutoMapper
{
  public class Mapper : IMapper, IMapperBase, IInternalRuntimeMapper, IRuntimeMapper
  {
    private readonly IGlobalConfiguration _configuration;
    private readonly Func<Type, object> _serviceCtor;

    public Mapper(IConfigurationProvider configuration)
      : this(configuration, configuration.Internal().ServiceCtor)
    {
    }

    public Mapper(IConfigurationProvider configuration, Func<Type, object> serviceCtor)
    {
      this._configuration = (IGlobalConfiguration) configuration ??
      throw new ArgumentNullException(nameof (configuration));
      this._serviceCtor = serviceCtor ?? throw new NullReferenceException(nameof (serviceCtor));
      this.DefaultContext = new ResolutionContext((IInternalRuntimeMapper) this);
    }

    internal ResolutionContext DefaultContext { get; }

    ResolutionContext IInternalRuntimeMapper.DefaultContext => this.DefaultContext;

    Func<Type, object> IInternalRuntimeMapper.ServiceCtor => this._serviceCtor;

    public IConfigurationProvider ConfigurationProvider =>
    (IConfigurationProvider) this._configuration;

    public TDestination Map<TDestination>(object source) =>
    this.Map<object, TDestination>(source, default (TDestination));

    public TDestination Map<TDestination>(
      object source,
      Action<IMappingOperationOptions<object, TDestination>> opts)
    {
      return this.Map<object, TDestination>(source, default (TDestination), opts);
    }

    public TDestination Map<TSource, TDestination>(TSource source) =>
     this.Map<TSource, TDestination>(source, default (TDestination));

    public TDestination Map<TSource, TDestination>(
      TSource source,
      Action<IMappingOperationOptions<TSource, TDestination>> opts)
    {
      return this.Map<TSource, TDestination>(source, default (TDestination), opts);
    }

    public TDestination Map<TSource, TDestination>(TSource source,
    TDestination destination) =>
    this.MapCore<TSource, TDestination>(source, destination, this.DefaultContext);

    public TDestination Map<TSource, TDestination>(
      TSource source,
      TDestination destination,
      Action<IMappingOperationOptions<TSource, TDestination>> opts)
    {
      return this.MapWithOptions<TSource, TDestination>(source, destination, opts);
    }

    public object Map(object source, Type sourceType, Type destinationType) =>
     this.Map(source, (object) null, sourceType, destinationType);

    public object Map(
      object source,
      Type sourceType,
      Type destinationType,
      Action<IMappingOperationOptions<object, object>> opts)
    {
      return this.Map(source, (object) null, sourceType, destinationType, opts);
    }

    public object Map(object source, object destination, Type sourceType,
    Type destinationType) => this.MapCore<object, object>(
      source, destination, this.DefaultContext, sourceType, destinationType);

    public object Map(
      object source,
      object destination,
      Type sourceType,
      Type destinationType,
      Action<IMappingOperationOptions<object, object>> opts)
    {
      return this.MapWithOptions<object, object>(
        source, destination, opts, sourceType, destinationType);
    }

    public IQueryable<TDestination> ProjectTo<TDestination>(
      IQueryable source,
      object parameters,
      params Expression<Func<TDestination, object>>[] membersToExpand)
    {
      return source.ProjectTo<TDestination>(
        this.ConfigurationProvider, parameters, membersToExpand);
    }

    public IQueryable<TDestination> ProjectTo<TDestination>(
      IQueryable source,
      IDictionary<string, object> parameters,
      params string[] membersToExpand)
    {
      return source.ProjectTo<TDestination>(
        this.ConfigurationProvider, parameters, membersToExpand);
    }

    public IQueryable ProjectTo(
      IQueryable source,
      Type destinationType,
      IDictionary<string, object> parameters,
      params string[] membersToExpand)
    {
      return source.ProjectTo(destinationType,
      this.ConfigurationProvider, parameters, membersToExpand);
    }

    TDestination IInternalRuntimeMapper.Map<TSource, TDestination>(
      TSource source,
      TDestination destination,
      ResolutionContext context,
      Type sourceType,
      Type destinationType,
      MemberMap memberMap)
    {
      return this.MapCore<TSource, TDestination>(
        source, destination, context, sourceType, destinationType, memberMap);
    }

    private TDestination MapWithOptions<TSource, TDestination>(
      TSource source,
      TDestination destination,
      Action<IMappingOperationOptions<TSource, TDestination>> opts,
      Type sourceType = null,
      Type destinationType = null)
    {
      MappingOperationOptions<TSource, TDestination> options =
       new MappingOperationOptions<TSource, TDestination>(this._serviceCtor);
      opts((IMappingOperationOptions<TSource, TDestination>) options);
      Action<TSource, TDestination> beforeMapAction = options.BeforeMapAction;
      if (beforeMapAction != null)
        beforeMapAction(source, destination);
      destination = this.MapCore<TSource, TDestination>(
        source, destination, new ResolutionContext((IInternalRuntimeMapper) this,
        (IMappingOperationOptions) options), sourceType, destinationType);
      Action<TSource, TDestination> afterMapAction = options.AfterMapAction;
      if (afterMapAction != null)
        afterMapAction(source, destination);
      return destination;
    }

    private TDestination MapCore<TSource, TDestination>(
      TSource source,
      TDestination destination,
      ResolutionContext context,
      Type sourceType = null,
      Type destinationType = null,
      MemberMap memberMap = null)
    {
      TypePair RequestedTypes = new TypePair(typeof (TSource), typeof (TDestination));
      TypePair RuntimeTypes;
      ref TypePair local = ref RuntimeTypes;
      Type SourceType = source?.GetType();
      if ((object) SourceType == null)
        SourceType = sourceType ?? typeof (TSource);
      Type DestinationType = destination?.GetType();
      if ((object) DestinationType == null)
        DestinationType = destinationType ?? typeof (TDestination);
      local = new TypePair(SourceType, DestinationType);
      MapRequest mapRequest = new MapRequest(RequestedTypes, RuntimeTypes, memberMap);
      return this._configuration.GetExecutionPlan<TSource, TDestination>(
        in mapRequest)(source, destination, context);
    }
  }
}

abp mapper

abp mapper 映射接口定义最顶层的接口

public interface IObjectMapper
{

    //提供映射的提供器,由它完成映射
    IAutoObjectMappingProvider AutoObjectMappingProvider { get; }

    TDestination Map<TSource, TDestination>(TSource source);

    TDestination Map<TSource, TDestination>(TSource source, TDestination destination);

}

//此处的 TContext 指的是模块
public interface IObjectMapper<TContext> : IObjectMapper
{

}

IObjectMapper<in TSource, TDestination> abp 提供的映射方式 用户自己写映射,最简单的方法

public interface IObjectMapper<in TSource, TDestination>
{
    TDestination Map(TSource source);
    TDestination Map(TSource source, TDestination destination);
}

ABP 会自动发现注册 MyCustomUserMapper, 在你使用 IObjectMapper 将用户映射到 UserDto 时会自 动使用自定义映射. 一个类可以为不同的对象实现多个 IObjectMapper<TSource, TDestination>.

public class MyCustomUserMapper : IObjectMapper<User, UserDto>, ITransientDependency
{

    public UserDto Map(User source)
    {
        //TODO: Create a new UserDto

    }

    public UserDto Map(User source, UserDto destination)
    {
        //TODO: Set properties of an existing UserDto
        return destination;

    }

}

如果上面的 IObjectMapper<TSource,TDestination> 麻烦可以使用如下的 abp 提供的更简单接口

原对象实现 IMapTo ,可以在对象上直接写映射关系,简单的映射可以这样做

public interface IMapTo<TDestination>
{
    TDestination MapTo();

    void MapTo(TDestination destination);
}

目标象实现 IMapFrom ,可以在对象上直接写映射关系,简单的映射可以这样做

public interface IMapFrom<in TSource>
{

    void MapFrom(TSource source);

}

IAutoObjectMappingProvider

如果 abp 提供的 IObjectMapper<TSource,TDestination> 不能满足,需要引入外部的映射提供器

namespace Volo.Abp.ObjectMapping;

public interface IAutoObjectMappingProvider
{
    TDestination Map<TSource, TDestination>(object source);
    TDestination Map<TSource, TDestination>(TSource source, TDestination destination);
}

public interface IAutoObjectMappingProvider<TContext> : IAutoObjectMappingProvider
{

}

abp 默认是不支持 auto mapper 的 所以这里的实现是空实现,可以使用 abp 自己定义的接口做映射 ,只有引入 auto mapper 的情况才会提供 auto mapper 的实现 IAutoObjectMappingProvider

public sealed class NotImplementedAutoObjectMappingProvider
   : IAutoObjectMappingProvider, ISingletonDependency
{
    public TDestination Map<TSource, TDestination>(
    object source)
    {
        throw new NotImplementedException($"Can not map from given object ({source})
         to {typeof(TDestination).AssemblyQualifiedName}.");
    }

    public TDestination Map<TSource, TDestination>(TSource source, TDestination destination)
    {
        throw new NotImplementedException($"Can no map from {
          typeof(TSource).AssemblyQualifiedName} to
          {typeof(TDestination).AssemblyQualifiedName}.");
    }
}

IObjectMapper 实现


namespace Volo.Abp.ObjectMapping;

public class DefaultObjectMapper : IObjectMapper, ITransientDependency
{
    protected static ConcurrentDictionary<string, MethodInfo> MethodInfoCache { get; } =
     new ConcurrentDictionary<string, MethodInfo>();

    //外部的映射提供器
    public IAutoObjectMappingProvider AutoObjectMappingProvider { get; }
    protected IServiceProvider ServiceProvider { get; }

    public DefaultObjectMapper(
        IServiceProvider serviceProvider,
        IAutoObjectMappingProvider autoObjectMappingProvider)
    {
        AutoObjectMappingProvider = autoObjectMappingProvider;
        ServiceProvider = serviceProvider;
    }

  //没有提供默认的目标类的映射
    public virtual TDestination Map<TSource, TDestination>(TSource source)
    {
        if (source == null)
        {
            return default!;
        }

        //IObjectMapper<TSource, TDestination> 这种处理
        using (var scope = ServiceProvider.CreateScope())
        {
            //先看自己定义的映射,这种最简单的映射
            var specificMapper = scope.ServiceProvider.
            GetService<IObjectMapper<TSource, TDestination>>();
            if (specificMapper != null)
            {
                return specificMapper.Map(source);
            }

            //先看自己定义的映射是集合类型的
            var result = TryToMapCollection<TSource,
            TDestination>(scope, source, default);
            if (result != null)
            {
                return result;
            }
        }

        //实现 MapTo<TDestination> 接口的源对象
        if (source is IMapTo<TDestination> mapperSource)
        {
            return mapperSource.MapTo();
        }

        //实现 IMapFrom<TSource> 接口的目标对象
        if (typeof(IMapFrom<TSource>).IsAssignableFrom(typeof(TDestination)))
        {
          try
          {
          //TODO: Check if TDestination has a proper constructor which takes TSource
          //TODO: Check if TDestination has an empty constructor
          ///(in this case, use MapFrom)
          //假设目标类型的构造器里有唯一参数的 source 的构造函数存在
          return (TDestination)Activator.CreateInstance(typeof(TDestination), source)!;
          }
          catch
          {
              //TODO: Remove catch when TODOs are implemented above
          }
        }
        //都不匹配使用外部侧提供器执行
        return AutoMap<TSource, TDestination>(source);
    }

    //提供了默认的目标类的映射
    public virtual TDestination Map<TSource, TDestination>(
      TSource source, TDestination destination)
    {
        if (source == null)
        {
            return default!;
        }

        using (var scope = ServiceProvider.CreateScope())
        {
            //先看自己定义的映射,这种最简单的映射
            var specificMapper = scope.ServiceProvider.GetService<
            IObjectMapper<TSource, TDestination>>();
            if (specificMapper != null)
            {
                return specificMapper.Map(source, destination);
            }

            //映射的是集合或素组类型 IObjectMapper<TSource, TDestination
            var result = TryToMapCollection(scope, source, destination);
            if (result != null)
            {
                return result;
            }
        }

        //如果对象实现了 IMapTo<TDestination> 接口,直接映射在源对象上实现的用户映射代码
        if (source is IMapTo<TDestination> mapperSource)
        {
            mapperSource.MapTo(destination);
            return destination;
        }

        //目标类型实现了 IMapFrom<TSource> 接口直接映射
        if (destination is IMapFrom<TSource> mapperDestination)
        {
            mapperDestination.MapFrom(source);
            return destination;
        }

        //上面的都不能映射,最好用外部提供的映射器实现
        return AutoMap(source, destination);
    }

    //IObjectMapper<,>  用户定义的集合或数组映射
    protected virtual TDestination? TryToMapCollection<TSource, TDestination>(
      IServiceScope serviceScope, TSource source, TDestination? destination)
    {
        //判断是否是映射集合
        if (!IsCollectionGenericType<TSource, TDestination>(
          out var sourceArgumentType, out var destinationArgumentType,
          out var definitionGenericType))
        {
            return default;
        }

        //先处理是用户自己生成映射的
        var mapperType = typeof(IObjectMapper<,>).MakeGenericType(
          sourceArgumentType, destinationArgumentType);
        var specificMapper = serviceScope.ServiceProvider.GetService(mapperType);
        if (specificMapper == null)
        {
            //skip, no specific mapper
            return default;
        }

        var cacheKey = $"{mapperType.FullName}_{(destination == null
        ? "MapMethodWithSingleParameter" : "MapMethodWithDoubleParameters")}";
        //先存入缓存,这里的缓存没有存在的必要性
        var method = MethodInfoCache.GetOrAdd(
            cacheKey,
            _ =>
            {
                return specificMapper
                    .GetType()
                    .GetMethods()
                    .First(x =>
                        //这里巧妙
                        x.Name == nameof(IObjectMapper<object, object>.Map) &&
                        //匹配方法参数个数
                        x.GetParameters().Length == (destination == null ? 1 : 2)
                    );
            }
        );

        var sourceList = source!.As<IList>();

        //生成一个空的集合和数组的目标对象
        var result = definitionGenericType.IsGenericType
            ? Activator.CreateInstance(definitionGenericType.MakeGenericType(
              destinationArgumentType))!.As<IList>()
            : Array.CreateInstance(destinationArgumentType, sourceList.Count);

        //目标类型默认不为空的,并且不是数组的,清空集合
        if (destination != null && !destination.GetType().IsArray)
        {
            //Clear destination collection if destination not an array,
            // We won't change array just same behavior as AutoMapper.
            destination.As<IList>().Clear();
        }

        for (var i = 0; i < sourceList.Count; i++)
        {
            var invokeResult = destination == null
                ? method.Invoke(specificMapper, new [] { sourceList[i] })!
                : method.Invoke(specificMapper, new [] { sourceList[i],
                Activator.CreateInstance(destinationArgumentType)! })!;

            if (definitionGenericType.IsGenericType)
            {
                //返回值集合添加,
                result.Add(invokeResult);
                //目标参数添加
                destination?.As<IList>().Add(invokeResult);
            }
            else
            {
                result[i] = invokeResult;
            }
        }

        if (destination != null && destination.GetType().IsArray)
        {
            //Return the new collection if destination is an array,
            // We won't change array just same behavior as AutoMapper.
            return (TDestination)result;
        }

        //Return the destination if destination exists.
        // The parameter reference equals with return object.
        return destination ?? (TDestination)result;
    }

    //映射双方是否是集合类型
    protected virtual bool IsCollectionGenericType<TSource,
    TDestination>(out Type sourceArgumentType,
    out Type destinationArgumentType, out Type definitionGenericType)
    {
        sourceArgumentType = default!;
        destinationArgumentType = default!;
        definitionGenericType = default!;

        //不是泛型不是集合类型
        if ((!typeof(TSource).IsGenericType && !typeof(TSource).IsArray) ||
            (!typeof(TDestination).IsGenericType && !typeof(TDestination).IsArray))
        {
            return false;
        }

        var supportedCollectionTypes = new[]
        {
            typeof(IEnumerable<>),
            typeof(ICollection<>),
            typeof(Collection<>),
            typeof(IList<>),
            typeof(List<>)
        };

        if (typeof(TSource).IsGenericType && supportedCollectionTypes.Any(
          x => x == typeof(TSource).GetGenericTypeDefinition()))
        {
            sourceArgumentType = typeof(TSource).GenericTypeArguments[0];
        }

        if (typeof(TSource).IsArray)
        {
            sourceArgumentType = typeof(TSource).GetElementType()!;
        }

        if (sourceArgumentType == default!)
        {
            return false;
        }

        definitionGenericType = typeof(List<>);

        if (typeof(TDestination).IsGenericType && supportedCollectionTypes.Any(
          x => x == typeof(TDestination).GetGenericTypeDefinition()))
        {
          destinationArgumentType = typeof(TDestination).GenericTypeArguments[0];

          if (typeof(TDestination).GetGenericTypeDefinition() == typeof(ICollection<>) ||
              typeof(TDestination).GetGenericTypeDefinition() == typeof(Collection<>))
          {
              definitionGenericType = typeof(Collection<>);
          }
        }

        if (typeof(TDestination).IsArray)
        {
            destinationArgumentType = typeof(TDestination).GetElementType()!;
            definitionGenericType = typeof(Array);
        }

        return destinationArgumentType != default!;
    }

    //使用外部的映射器
    protected virtual TDestination AutoMap<TSource, TDestination>(object source)
    {
        return AutoObjectMappingProvider.Map<TSource, TDestination>(source);
    }
    //使用外部的映射器
    protected virtual TDestination AutoMap<TSource, TDestination>(
      TSource source, TDestination destination)
    {
        return AutoObjectMappingProvider.Map<TSource, TDestination>(source, destination);
    }
}
//此处的上下文是模块
public class DefaultObjectMapper<TContext> : DefaultObjectMapper, IObjectMapper<TContext>
{

    public DefaultObjectMapper(
        IServiceProvider serviceProvider,
        IAutoObjectMappingProvider<TContext> autoObjectMappingProvider
        ) : base(
            serviceProvider,
            autoObjectMappingProvider)
    {

    }

}

AbpObjectMappingModule

public class AbpObjectMappingModule : AbpModule
{
    public override void PreConfigureServices(ServiceConfigurationContext context)
    {
        //给 IObjectAccessor<ServiceExposingActionList>  里加入 action
        //onServiceExposingContext 是在注入服务的时候,一个实现类及多个导出接口
        context.Services.OnExposing(onServiceExposingContext =>
        {
                //Register types for IObjectMapper<TSource, TDestination> if implements
                onServiceExposingContext.ExposedTypes.AddRange(
                //onServiceExposingContext.ImplementationType,
                //当前 ImplementationType 类型 是否满足 IObjectMapper<,> 接口约定
                //当前 ImplementationType 类型的导出类型加入 ImplementationType 的接口类型
                //只所以这样做是因为实现类如果有多个接口,默认注入的接口如果不是IObjectMapper<,>
                //这里就需要人为的去干预把  IObjectMapper<,>  类型的接口作为实现类的导出类型
                ReflectionHelper.GetImplementedGenericTypes(
                    onServiceExposingContext.ImplementationType,
                    typeof(IObjectMapper<,>)
                )
            );
        });
    }

    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        context.Services.AddTransient(
            typeof(IObjectMapper<>),
            typeof(DefaultObjectMapper<>)
        );
    }
}

abp AutoMapper

AutoMapperAutoObjectMappingProvider 提供器

获取 auto mapper 提供的 IMapper

public interface IMapperAccessor
{

    //获取 auto mapper 提供的 IMapper
    IMapper Mapper { get; }

}

internal class MapperAccessor : IMapperAccessor
{

    public IMapper Mapper { get; set; } = default!;

}

auto mapper IMapper 实现映射

public class AutoMapperAutoObjectMappingProvider : IAutoObjectMappingProvider
{
    public IMapperAccessor MapperAccessor { get; }

    public AutoMapperAutoObjectMappingProvider(IMapperAccessor mapperAccessor)
    {
        MapperAccessor = mapperAccessor;
    }

    public virtual TDestination Map<TSource, TDestination>(object source)
    {
        return MapperAccessor.Mapper.Map<TDestination>(source);
    }

    public virtual TDestination Map<TSource, TDestination>(
      TSource source, TDestination destination)
    {
        return MapperAccessor.Mapper.Map(source, destination);
    }
}

public class AutoMapperAutoObjectMappingProvider<TContext> :
AutoMapperAutoObjectMappingProvider, IAutoObjectMappingProvider<TContext>
{
    public AutoMapperAutoObjectMappingProvider(IMapperAccessor mapperAccessor)
        : base(mapperAccessor)
    {
    }
}

IAbpAutoMapperConfigurationContext 配置上下文

配置 auto mapper 的 profile 的上下文

namespace Volo. Abp. AutoMapper;

public interface IAbpAutoMapperConfigurationContext
{

    //提供的 profile 文件,里面包含映射关系的表达式
    IMapperConfigurationExpression MapperConfiguration { get; }

    IServiceProvider ServiceProvider { get; }

}

public class AbpAutoMapperConfigurationContext : IAbpAutoMapperConfigurationContext
{

    public IMapperConfigurationExpression MapperConfiguration { get; }

    public IServiceProvider ServiceProvider { get; }

    public AbpAutoMapperConfigurationContext(
        IMapperConfigurationExpression mapperConfigurationExpression,
        IServiceProvider serviceProvider)
    {
        MapperConfiguration = mapperConfigurationExpression;
        ServiceProvider = serviceProvider;

    }

}

AbpAutoMapperOptions

namespace Volo.Abp.AutoMapper;

public class AbpAutoMapperOptions
{
    //配置上下文
    public List<Action<IAbpAutoMapperConfigurationContext>> Configurators { get; }

    public ITypeList<Profile> ValidatingProfiles { get; set; }

    public AbpAutoMapperOptions()
    {
        Configurators = new List<Action<IAbpAutoMapperConfigurationContext>>();
        ValidatingProfiles = new TypeList<Profile>();
    }

    public void AddMaps<TModule>(bool validate = false)
    {
        //模块所属程序集
        var assembly = typeof(TModule).Assembly;

        Configurators.Add(context =>
        {
            //把模块所在程序集内部的 profile 映射文件加入上下文的
            //IMapperConfigurationExpression
            context.MapperConfiguration.AddMaps(assembly);
        });

        //是否进行配置验证,有可能配置的字段无法匹配,提前进行验证
        if (validate)
        {
            var profileTypes = assembly
                .DefinedTypes
                .Where(type => typeof(Profile).IsAssignableFrom(type)
                 && !type.IsAbstract && !type.IsGenericType);

            foreach (var profileType in profileTypes)
            {
                //需要验证的 profile 文件
                ValidatingProfiles.Add(profileType);
            }
        }
    }

    public void AddProfile<TProfile>(bool validate = false)
        where TProfile : Profile, new()
    {
        Configurators.Add(context =>
        {
            context.MapperConfiguration.AddProfile<TProfile>();
        });

        if (validate)
        {
            ValidateProfile(typeof(TProfile));
        }
    }

    public void ValidateProfile<TProfile>(bool validate = true)
        where TProfile : Profile
    {
        ValidateProfile(typeof(TProfile), validate);
    }

    public void ValidateProfile(Type profileType, bool validate = true)
    {
        if (validate)
        {
            ValidatingProfiles.AddIfNotContains(profileType);
        }
        else
        {
            ValidatingProfiles.Remove(profileType);
        }
    }
}

注册 profile 给 AbpAutoMapperOptions

[DependsOn(typeof(AbpAutoMapperModule))]
public class MyModule : AbpModule
{

    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        //注入 auto mapper 提供额提供器
        context. Services. AddAutoMapperObjectMapper();

        //这种方式是把 profile 全局加入 AbpAutoMapperOptions 配置项,所有模块共用 profile
        Configure<AbpAutoMapperOptions>(options =>
        {
            //把模块内的profile 映射加入配置对象的上下文,
            options. AddMaps<MyModule>();
            //options. AddMaps<MyModule>(validate: true);
            //也可以单独的添加 profile 文件
        });

    }

}

AbpAutoMapperModule

namespace Volo.Abp.AutoMapper;

[DependsOn(
    typeof(AbpObjectMappingModule),
    typeof(AbpObjectExtendingModule),
    typeof(AbpAuditingModule)
)]
public class AbpAutoMapperModule : AbpModule
{
  public override void PreConfigureServices(ServiceConfigurationContext context)
  {
      context.Services.AddConventionalRegistrar(new AbpAutoMapperConventionalRegistrar());
  }

  public override void ConfigureServices(ServiceConfigurationContext context)
  {
      //使用 auto mapper 作为提供器
      context.Services.AddAutoMapperObjectMapper();

      //通过工厂注入auto mapper 的 IConfigurationProvider 实现 mapperConfiguration
      //auto mapper 内部需要使用  IConfigurationProvider
      context.Services.AddSingleton<IConfigurationProvider>(sp =>
      {
          //局部 scope
          using (var scope = sp.CreateScope())
          {
              //加载配置项目,里面有所有模块的profile 文件
              var options = scope.ServiceProvider.GetRequiredService<
              IOptions<AbpAutoMapperOptions>>().Value;

              //加载通过  MapperConfiguration  配置的映射关系,参考 auto mapper 官方文档
              //这个是在哪里注入的不明确
              var mapperConfigurationExpression = sp.GetRequiredService<
              IOptions<MapperConfigurationExpression>>().Value;

              //用 mapperConfigurationExpression 生成一个上下文
              var autoMapperConfigurationContext =
               new AbpAutoMapperConfigurationContext(
                mapperConfigurationExpression, scope.ServiceProvider);

              // 把配置类的 profile 加入 autoMapperConfigurationContext
              foreach (var configurator in options.Configurators)
              {
                  //configurator 是个委托,这个委托负责把 profile 配置加入上下文
                  configurator(autoMapperConfigurationContext);
              }

              //生成 MapperConfiguration
              var mapperConfiguration = new MapperConfiguration(
                mapperConfigurationExpression);

              foreach (var profileType in options.ValidatingProfiles)
              {
                  //使用 mapperConfiguration 进行配置的验证,具体看 auto mapper 文档
                  mapperConfiguration.Internal().AssertConfigurationIsValid(
                    ((Profile)Activator.CreateInstance(profileType)).ProfileName);
              }

              // 返回  auto mapper  的  mapperConfiguration
              return mapperConfiguration;
          }
      });

      //注入  auto mapper 的 IMapper
      context.Services.AddTransient<IMapper>(sp => sp.GetRequiredService<
      IConfigurationProvider>().CreateMapper(sp.GetService));
      //注入 abp 包装的 MapperAccessor 对象
      context.Services.AddTransient<MapperAccessor>(sp => new MapperAccessor()
      {
          Mapper = sp.GetRequiredService<IMapper>()
      });
      //注入 IMapperAccessor ,abp 归根结底是通过 通过  IMapperAccessor 拿到 最终的  IMapper
      //IMapper 本质又是通过 IConfigurationProvider 生成的
      //在 abp 内部使用的是 IMapperAccessor 进行的 映射
      context.Services.AddTransient<IMapperAccessor>(
        provider => provider.GetRequiredService<MapperAccessor>());
  }
}

约定的注入 这些注入的接口是 auto mapper 定义的

public class AbpAutoMapperConventionalRegistrar : DefaultConventionalRegistrar
{

    protected readonly Type[] OpenTypes = {
            typeof(IValueResolver<,,>),
            typeof(IMemberValueResolver<,,,>),
            typeof(ITypeConverter<,>),
            typeof(IValueConverter<,>),
            typeof(IMappingAction<,>)
        };

    protected override bool IsConventionalRegistrationDisabled(Type type)
    {
        return !type. GetInterfaces(). Any(
          x => x. IsGenericType && OpenTypes. Contains(x. GetGenericTypeDefinition())) ||
               base. IsConventionalRegistrationDisabled(type);

    }

    protected override ServiceLifetime? GetDefaultLifeTimeOrNull(Type type)
    {
        return ServiceLifetime. Transient;

    }

}

注入 auto mapper 的 AutoMapperAutoObjectMappingProvider 映射提供器

public static class AbpAutoMapperServiceCollectionExtensions
{
    public static IServiceCollection AddAutoMapperObjectMapper(
      this IServiceCollection services)
    {
        //IAutoObjectMappingProvider 提供映射的提供器
        //因为之前 abp mapper 模块已经注入过 nullObjectMappingProvider 提供器,
        //所以这里使用服务替换
        return services.Replace(
            ServiceDescriptor.Transient<IAutoObjectMappingProvider,
             AutoMapperAutoObjectMappingProvider>()
        );
    }

    public static IServiceCollection AddAutoMapperObjectMapper<TContext>(
      this IServiceCollection services)
    {
        return services.Replace(
            ServiceDescriptor.Transient<IAutoObjectMappingProvider<TContext>,
             AutoMapperAutoObjectMappingProvider<TContext>>()
        );
    }
}

按模块隔离 profile

[DependsOn(typeof(AbpAutoMapperModule))]
public class MyModule : AbpModule
{

    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        //注入 auto mapper 提供额提供器
        context.Services.AddAutoMapperObjectMapper<MyModule>();

        //这种方式是把 profile 全局加入 AbpAutoMapperOptions 配置项,所有模块共用 profile
        Configure<AbpAutoMapperOptions>(options =>
        {
            //把模块内的profile 映射加入配置对象的上下文,
            options. AddMaps<MyModule>();
            //options. AddMaps<MyModule>(validate: true);
            //也可以单独的添加 profile 文件
        });

    }

}
👍🎉🎊