TinyMapper 对象映射框架的封装

2023年7月19日 854点热度 2人点赞 0条评论
内容纲要

最近使用了一个 TinyMapper 对象映射框架,喜欢它的简单。
TinyMapper 文档地址: http://tinymapper.net/

TinyMapper 极其简单,一个静态类即可:

TinyMapper.Bind<Person, PersonDto>();

var person = new Person
{
    Id = Guid.NewGuid(),
    FirstName = "John",
    LastName = "Doe"
};

var personDto = TinyMapper.Map<PersonDto>(person);

// with mapping members ignored and bind members with different names/types

TinyMapper.Bind<Person, PersonDto>(config =>
{
    config.Ignore(x => x.Id);
    config.Ignore(x => x.Email);
    config.Bind(source => source.LastName, target => target.Surname);
    config.Bind(target => source.Emails, typeof(List<string>));
});

var person = new Person
{
    Id = Guid.NewGuid(),
    FirstName = "John",
    LastName = "Doe",
    Emails = new List<string>{"support@tinymapper.net", "MyEmail@tinymapper.net"}
};

var personDto = TinyMapper.Map<PersonDto>(person);

但是它本身提供的方法不多,所以需要直接封装做一个配置接口。

    public class Mapper
    {
        public void Bind<TSource, TTarget>()
        {
            TinyMapper.Bind<TSource, TTarget>();
        }

        public static void Bind(Type sourceType, Type targetType)
        {
            TinyMapper.Bind(sourceType, targetType);
        }

        public static void Bind<TSource, TTarget>(Action<IBindingConfig<TSource, TTarget>> config)
        {
            TinyMapper.Bind<TSource, TTarget>(config);
        }
    }
    /// <summary>
    /// 对象映射
    /// </summary>
    public interface IMapper
    {
        /// <summary>
        /// 对象映射
        /// </summary>
        void InitMapper(Mapper map);
    }

然后在需要的地方:

    internal class DataSourceMapper : IMapper
    {
        public void InitMapper(Mapper map)
        {
            map.Bind<DataSourceEntity, DataSourceVO>();
            map.Bind<DataSourceVO, DataSourceEntity>();
        }
    }

然后写个扩展,扫描所有程序集,自动加入映射即可:

    internal static class MapperExtensions
    {
        public static void AddMapper(this IServiceCollection services)
        {
            var map = new Mapper();
            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                var assemblyName = assembly.GetName();
                if (assemblyName == null || string.IsNullOrEmpty(assemblyName.Name)) continue;
                if (assemblyName.Name.StartsWith("System") || assemblyName.Name.StartsWith("Microsoft")) continue;
                foreach (var type in assembly.GetTypes())
                {
                    if (type.GetInterfaces().Any(x=>x == typeof(IMapper)))
                    {
                        var mapper = Activator.CreateInstance(type) as IMapper;
                        if(mapper == null)
                        {
                            Debug.Assert(mapper == null);
                            continue;
                        }
                        // 初始化 Mapper 关系
                        mapper.InitMapper(map);
                    }
                }
            }
        }
    }

痴者工良

高级程序员劝退师

文章评论