【C#/.NET】不用AutoMapper,我用啥呢?TinyMapper

TinyMapper简介

TinyMapper是一个.NET平台下的一个轻量级对象映射工具,号称是.Net平台下最快的对象映射组件,性能是AutoMapper的6倍。今天我们来在.Net6下演示如何快速使用这个组件。.

【C#/.NET】不用AutoMapper,我用啥呢?TinyMapper

官网地址:http://tinymapper.net/

安装

1.新建一个Web Api项目

【C#/.NET】不用AutoMapper,我用啥呢?TinyMapper

2.安装Nuget包

【C#/.NET】不用AutoMapper,我用啥呢?TinyMapper

创建实体以及映射类型

1.新建一个Model类,里面包括数据库实体和DTO

namespace TinymapperDemo.Models
{
    /// <summary>
    /// 数据库实体DTO
    /// </summary>
    public class PersonDto 
    {
        public string? Name { get; set; }
        public string? Address { get; set; }
        public string? Phone { get; set; }
    }

    /// <summary>
    /// 数据库实体 用的 record 类型标记
    /// </summary>
    /// <param name="Id"></param>
    /// <param name="UserName"></param>
    /// <param name="City"></param>
    /// <param name="Street"></param>
    /// <param name="Phone"></param>
    public record Person(int Id,
        string UserName,
        string City,
        string Street,
        string Phone);

}

从数据库获取实体数据

新建一个UserManger类,代替仓储模拟从数据库获取实体数据

public class UserManage : IUserManage
{
        /// <summary>
        /// 模拟从数据库获取数据
        /// </summary>
        /// <returns></returns>
        public Person[] GetPerson()
        {
            return new[] {
                new Person(1,"Jarry","Suzhou","Guan qian","1232322323"),
                new Person(1,"Test","Suzhou","Shan tang","3232324332")
            };
        }
}

namespace TinymapperDemo.Services
{
    public interface IUserManage
    {
        Person[] GetPerson();
    }
}

服务获取

生成UserService服务,提供给API接口调用

namespace TinymapperDemo.Services
{
    public class UserService:IUserService
    {
        private readonly IUserManage userManage;

        public UserService(IUserManage userManage)
        {
            this.userManage = userManage;
        }

        public PersonDto GetPersonDto(string name)
        {
            var persons = userManage.GetPerson();
            var model =persons.FirstOrDefault(f => f.UserName.IndexOf(name) >= 0);
            // 常规转化方法如下
            //return new PersonDto()
            //{
            //    Name = model?.UserName,
            //    Address = model?.City + model?.Street,
            //    Phone = model?.Phone
            //};

            //  使用TinyMapper 转化 
            // 除了下面这步转化呢  还需要再Program.cs 里面配置一下  TinyMapper.Bind<Person, PersonDto>();  // 必不可省
            return TinyMapper.Map<PersonDto>(model);
        }
    }

    public interface IUserService
    {
        PersonDto GetPersonDto(string name);
    }
}

服务注册

builder.Services.AddSingleton<IUserManage, UserManage>();  // 注册仓储
builder.Services.AddSingleton<IUserService, UserService>();  // 注册服务

TinyMapper.Bind<Person, PersonDto>();  // 必不可省

额外用法

1:对于TinyMapper简单类转化用法,我们可以手动配置,比如:

// Person 为实体  PersonDto 为Dto 实体转化到Dto 
TinyMapper.Bind<Person, PersonDto>(c =>
     {
         c.Ignore(f => f.Id);  // 忽略字段
         c.Bind(s => s.UserName, d => d.Name);
         c.Bind(s => s.City, d => d.Address);
         c.Bind(s => s.Phone, d => d.Phone);
     }
);

2.对于复杂字段,我们可以自定义转化配置:用法如下:
首先新建一个转化类:CustomConveter 继承TypeConverter这个抽象类。

public class CustomConveter: TypeConverter {}

接着重写两个基方法 CanConvertTo ConvertTo

 public class CustomConveter: TypeConverter
    {
        public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType)
        {
            return destinationType== typeof(PersonDto);
        }
        public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType)
        {
            var conveterValue = value as Person;
            var personDto = new PersonDto
            {
                Address = conveterValue?.City + conveterValue?.Street,  // 地址拼接为 城市+街道的形式
                Phone = conveterValue?.Phone,
                Name = conveterValue?.UserName
            };
            return personDto;

        }
    }

最后我们在实体类上绑上上面写好的自定义转化特性

[TypeConverter(typeof(CustomConveter))]
    public record Person(int Id,
        string UserName,
        string City,
        string Street,
        string Phone);

大功告成。。。。。。以上就是官网演示的方法,我在.Net6 平台上面复现了一下,感谢观阅!