首页 > 其他 > 详细

对象映射模块

时间:2019-07-25 11:02:37      阅读:199      评论:0      收藏:0      [点我收藏+]

一、ObjectMapping 对象映射

定义的接口IObjectMapper,和默认的实现类DefaultObjectMapper

其中AutoMapperObjectMapper是替换实现

/// <summary>
    /// Defines a simple interface to automatically map objects.
    /// </summary>
    public interface IObjectMapper
    {
        /// <summary>
        /// Converts an object to another. Creates a new object of <see cref="TDestination"/>.
        /// </summary>
        /// <typeparam name="TDestination">Type of the destination object</typeparam>
        /// <typeparam name="TSource">Type of the source object</typeparam>
        /// <param name="source">Source object</param>
        TDestination Map<TSource, TDestination>(TSource source);

        /// <summary>
        /// Execute a mapping from the source object to the existing destination object
        /// </summary>
        /// <typeparam name="TSource">Source type</typeparam>
        /// <typeparam name="TDestination">Destination type</typeparam>
        /// <param name="source">Source object</param>
        /// <param name="destination">Destination object</param>
        /// <returns>Returns the same <see cref="destination"/> object after mapping operation</returns>
        TDestination Map<TSource, TDestination>(TSource source, TDestination destination);
    }

    /// <summary>
    /// Maps an object to another.
    /// Implement this interface to override object to object mapping for specific types.
    /// </summary>
    /// <typeparam name="TSource"></typeparam>
    /// <typeparam name="TDestination"></typeparam>
    public interface IObjectMapper<in TSource, TDestination>
    {
        /// <summary>
        /// Converts an object to another. Creates a new object of <see cref="TDestination"/>.
        /// </summary>
        /// <param name="source">Source object</param>
        TDestination Map(TSource source);

        /// <summary>
        /// Execute a mapping from the source object to the existing destination object
        /// </summary>
        /// <param name="source">Source object</param>
        /// <param name="destination">Destination object</param>
        /// <returns>Returns the same <see cref="destination"/> object after mapping operation</returns>
        TDestination Map(TSource source, TDestination destination);
    }

2、AutoMapper

AutoMapper是一个对象与对象的映射器

首先,您需要使用源类型和目标类型。目标类型的设计可能会受到其所在层的影响,但只要成员的名称与源类型的成员相匹配,AutoMapper就可以发挥最佳效果

您现在必须使用Mapper.Initializenew MapperConfiguration()来初始化AutoMapper。如果您希望保持静态使用,请使用Mapper.Initialize

如果你有很多的Mapper.CreateMap调用,把它们移动到一个Profile,或者Mapper.Initialize,在启动时调用一次。

Mapper.Initialize(cfg => cfg.CreateMap<Order, OrderDto>());
//or
var config = new MapperConfiguration(cfg => cfg.CreateMap<Order, OrderDto>());

定义属性

1、AutoMapAttribute,双向映射

  如 [AutoMap(typeof(MyClass2), typeof(MyClass3))] private class MyClass1

    foreach (var targetType in TargetTypes)
            {
                configuration.CreateMap(type, targetType, MemberList.Source);
                configuration.CreateMap(targetType, type, MemberList.Destination);
            }

2、AutoMapFromAttribute

如:[AutoMapFrom(typeof(MyClass3))]  即MyClass3就目标类型

 foreach (var targetType in TargetTypes)
            {
                configuration.CreateMap(targetType, type, MemberList);
            }

3、 AutoMapToAttribute  

如:[AutoMapTo(typeof(MyClass3))] private class MyClass2    即MyClass3是目标类型,而MyClass2是源类型

            foreach (var targetType in TargetTypes)
            {
                configuration.CreateMap(type, targetType, MemberList);
            }

上述的应用,在模块的应用初始化前OnPreApplicationInitialization,实行操作CreateMap操作

1、首先初始化类型查找器ITypeFinder

2、查找相关的属性数组

  var types = typeFinder.Types.Where(type =>
                {
                    var typeInfo = type.GetTypeInfo();
                    return typeInfo.IsDefined(typeof(AutoMapAttribute)) ||
                           typeInfo.IsDefined(typeof(AutoMapFromAttribute)) ||
                           typeInfo.IsDefined(typeof(AutoMapToAttribute));
                }
            ).ToArray();

在上下文里IAbpAutoMapperConfigurationContext,属性IMapperConfigurationExpression,执行上述的CreateMap的操作

  public static void CreateAutoAttributeMaps(this IMapperConfigurationExpression configuration, Type type)
        {
            foreach (var autoMapAttribute in type.GetTypeInfo().GetCustomAttributes<AutoMapAttributeBase>())
            {
                autoMapAttribute.CreateMap(configuration, type);
            }
        }

二、对Profile的配置

      void ConfigureAll(IAbpAutoMapperConfigurationContext ctx)
                    {
                        FindAndAutoMapTypes(ctx); //针对属性进行配置
                        foreach (var configurator in options.Configurators) //针对profile进行配置
                        {
                            configurator(ctx);
                        }
                    }

                    void ValidateAll(IConfigurationProvider config)
                    {
                        foreach (var profileType in options.ValidatingProfiles)
                        {
                            config.AssertConfigurationIsValid(((Profile)Activator.CreateInstance(profileType)).ProfileName);
                        }
                    }

重点看AbpAutoMapperOptions的AddProfile方法,这里面在模块设置里进行配置

手写映射配置代码虽然繁琐,但具有可测试的优点。AutoMapper背后的设计灵感之一是不仅消除了自定义映射代码,而且消除了手动测试的需要。由于从源到目标的映射是基于约定的,因此您仍需要测试配置

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

            if (validate)
            {
                ValidatingProfiles.Add<TProfile>();
            }
        }

三、使用例子

模块的使用进行配置

          public override void ConfigureServices(ServiceConfigurationContext context)
            {
                Configure<AbpAutoMapperOptions>(options =>
                {
                    options.UseStaticMapper = false;

                    options.AddProfile<ValidatedProfile>(true);
                    options.AddProfile<NonValidatedProfile>();
                });
            }

 

 

手写映射配置代码虽然繁琐,但具有可测试的优点。AutoMapper背后的设计灵感之一是不仅消除了自定义映射代码,而且消除了手动测试的需要。由于从源到目标的映射是基于约定的,因此您仍需要测试配置
作者:慕姐8265434
链接:http://www.imooc.com/article/273854?block_id=tuijian_wz
来源:慕课网

对象映射模块

原文:https://www.cnblogs.com/cloudsu/p/11231033.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!