当前位置: 移动技术网 > IT编程>开发语言>.net > 在ABP中灵活使用AutoMapper

在ABP中灵活使用AutoMapper

2019年08月01日  | 移动技术网IT编程  | 我要评论

暧昧同居冷血大兵,heavy的比较级和最高级,大荒艳旅

demo地址:abp.windowsservice
该文章是系列文章 基于.netcore和abp框架如何让windows服务执行quartz定时作业 的其中一篇。

automapper简介

automapper是一个简单的小型的对象映射库,是为了解决一个繁杂的问题 - 将一个对象映射到另一个对象的到处乱飞的胶水代码。这类胶水代码非常沉闷,让人怀疑自己的工作的价值性。automapper就是你摆脱此类代码的福音。
官网地址:
github地址:https://github.com/automapper/automapper

automapper的简单使用

这里拿官网的例子做一个简单说明,主要是为了引出在abp中是如何使用的,来进行对比。使用automapper将遇到的最经典的两个场景。

  1. 最多遇到的场景,应该是接口返回的dto和数据库entity,出于敏感信息保护或者减少接口返回数据等等的原因,dto返回的属性或者字段有所删减,也就是说需要映射的属性或者字段属性名称一致。
  2. dto和entity名称不一致,甚至类型不同,相互转换时甚至需要对数据有处理。

下面的例子就是字段属性基本一致。

public class order
{
        public string ordername { get;set; }
        public string phonenumber { get;set; }
}
public class orderdto
{
        public string ordername { get;set; }
}
var config = new mapperconfiguration(cfg => cfg.createmap<order, orderdto>());
var mapper = config.createmapper();
orderdto dto = mapper.map<orderdto>(order);

或者

var config = new mapperconfiguration(cfg => cfg.createmap<order, orderdto>());
var mapper = new mapper(config);
orderdto dto = mapper.map<orderdto>(order);

abp.automapper的简单使用

abp.automapper的官网文档:https://aspnetboilerplate.com/pages/documents/object-to-object-mapping
abp.automapper的nuget地址:https://www.nuget.org/packages/abp.automapper

添加nuget包

install-package abp.automapper

添加abpautomappermodule模块

[dependson(typeof(abpautomappermodule))]
public class myjobcoremodule : abpmodule
{
}

指定映射关系

自动映射

你可以通过属性automap, automapfrom, automapto指定映射关系
改造上面的之前的例子

[automapfrom(typeof(order))]
public class orderdto
{
        public string ordername { get;set; }
}

或者

[automapto(typeof(orderdto))]
public class order
{
        public string ordername { get;set; }
        public string phonenumber { get;set; }
}

但是属性的使用场景比较窄,稍微复杂一点的场景就无法满足,比如,指定忽略一些字段,或者字段名称不同需要显示指定。

自定义映射

[dependson(typeof(abpautomappermodule))]
public class myjobcoremodule : abpmodule
{
    public override void preinitialize()
    {
        configuration.modules.abpautomapper().configurators.add(config =>
        {
            config.createmap<order, orderdto>();
        });
    }
}

忽略字段

config.createmap<order, orderdto>()
          .formember(u => u.phonenumber, options => options.ignore());

字段名不一致

orderdto增加手机号字段tel,映射order字段phonenumber

    public class orderdto
    {
        public string ordername { get; set; }
        public string tel { get; set; }
    }
config.createmap<order, orderdto>()
          .formember(u => u.tel, options => options.mapfrom(input => input.phonenumber));

需要对字段进行处理后返回

比如,隐藏11位手机号的中间4位

private static string hidetel(string input)
{
    if (string.isnullorempty(input))
    {
        return string.empty;
    }
    var outreplace = regex.replace(input, "(\\d{3})\\d{4}(\\d{4})", "$1****$2");
    return outreplace;
}
config.createmap<order, orderdto>()
          .formember(u => u.tel, options => options.mapfrom(input => hidetel(input.phonenumber)));

拼接映射

又比如orderdto新增邮寄地址和收货地址

namespace demo.myjob.entity.dto
{
    public class orderdto
    {
        public string ordername { get; set; }
        public string tel { get; set; }
        public string postaladdress { get; set; }
        public string deliveryaddress { get; set; }
    }
}

order的相关表orderaddress类型定义

namespace demo.myjob.entity
{
    public class orderaddress
    {
        public string orderid { get; set; }
        public string postaladdress { get; set; }
        public string deliveryaddress { get; set; }
    }
}

这时就需要orderaddress和order的数据相结合映射orderdto,怎么实现呢?借助元组tuple。

config.createmap<(order, orderaddress), orderdto>()
          .formember(u => u.tel, options => options.mapfrom(input => hidetel(input.item1.phonenumber)))
          .formember(u => u.ordername, options => options.mapfrom(input => input.item1.ordername))
          .formember(u => u.postaladdress, options => options.mapfrom(input => input.item2.postaladdress))
          .formember(u => u.deliveryaddress, options => options.mapfrom(input => input.item2.deliveryaddress))
          ;

精简配置

需要自定义的映射关系过多时,会使得preinitialize变大,不便于管理和查看。

public override void preinitialize()
{
    configuration.modules.abpautomapper().configurators.add(config =>
    {
        config.createmap<(order, orderaddress), orderdto>()
          .formember(u => u.tel, options => options.mapfrom(input => hidetel(input.item1.phonenumber)))
          .formember(u => u.ordername, options => options.mapfrom(input => input.item1.ordername))
          .formember(u => u.postaladdress, options => options.mapfrom(input => input.item2.postaladdress))
          .formember(u => u.deliveryaddress, options => options.mapfrom(input => input.item2.deliveryaddress))
          ;
    });
}

如何精简?新增类型mymapperprofile,继承automapper.profile

using system.text.regularexpressions;
using automapper;
using demo.myjob.entity;
using demo.myjob.entity.dto;

namespace demo.myjob.mapperprofiles
{
    class mymapperprofile : profile
    {
        private static string hidetel(string input)
        {
            if (string.isnullorempty(input))
            {
                return string.empty;
            }
            var outreplace = regex.replace(input, "(\\d{3})\\d{4}(\\d{4})", "$1****$2");
            return outreplace;
        }
        public mymapperprofile()
        {
            createmap<order, orderdto>()
                .formember(u => u.tel, options => options.mapfrom(input => hidetel(input.phonenumber)));

            createmap<(order, orderaddress), orderdto>()
                .formember(u => u.tel, options => options.mapfrom(input => hidetel(input.item1.phonenumber)))
                .formember(u => u.ordername, options => options.mapfrom(input => input.item1.ordername))
                .formember(u => u.postaladdress, options => options.mapfrom(input => input.item2.postaladdress))
                .formember(u => u.deliveryaddress, options => options.mapfrom(input => input.item2.deliveryaddress))
                ;
        }
    }
}

修改preinitialize

[dependson(typeof(abpautomappermodule))]
public class myjobcoremodule : abpmodule
{
    public override void preinitialize()
    {
        configuration.modules.abpautomapper().configurators.add(config =>
        {
            config.addmaps(typeof(myjobcoremodule));
        });
    }
}

abp.automapper版本低于4.8.0的可以修改为

config.addprofiles(typeof(myjobcoremodule));

以上就是如何在abp框架下灵活使用automapper的全部内容,谢谢阅读。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网