首页 > 学院 > 开发设计 > 正文

Automapper扩展方法

2019-11-17 02:30:36
字体:
来源:转载
供稿:网友

Automapper扩展方法

问题描述

系统中实现了一个自定义的PagedList

/// <summary>    /// Paged list interface    /// </summary>    public interface ipagedList    {        int PageIndex { get; }        int PageSize { get; }        int TotalCount { get; }        int TotalPages { get; }        bool HaspreviousPage { get; }        bool HasNextPage { get; }    }    /// <summary>    /// Paged list interface    /// </summary>    public interface IPagedList<T> : IList<T>, IPagedList    {    }/// <summary>    /// Paged list    /// </summary>    /// <typeparam name="T">T</typeparam>    [Serializable]    public class PagedList<T> : List<T>, IPagedList<T>     {        /// <summary>        /// Ctor        /// </summary>        /// <param name="source">source</param>        /// <param name="pageIndex">Page index</param>        /// <param name="pageSize">Page size</param>        public PagedList(IQueryable<T> source, int pageIndex, int pageSize)        {            int total = source.Count();            this.TotalCount = total;            this.TotalPages = total / pageSize;            if (total % pageSize > 0)                TotalPages++;            this.PageSize = pageSize;            this.PageIndex = pageIndex;            this.AddRange(source.Skip(pageIndex * pageSize).Take(pageSize).ToList());        }        /// <summary>        /// Ctor        /// </summary>        /// <param name="source">source</param>        /// <param name="pageIndex">Page index</param>        /// <param name="pageSize">Page size</param>        public PagedList(IList<T> source, int pageIndex, int pageSize)        {            TotalCount = source.Count();            TotalPages = TotalCount / pageSize;            if (TotalCount % pageSize > 0)                TotalPages++;            this.PageSize = pageSize;            this.PageIndex = pageIndex;            this.AddRange(source.Skip(pageIndex * pageSize).Take(pageSize).ToList());        }        /// <summary>        /// Ctor        /// </summary>        /// <param name="source">source</param>        /// <param name="pageIndex">Page index</param>        /// <param name="pageSize">Page size</param>        /// <param name="totalCount">Total count</param>        public PagedList(IEnumerable<T> source, int pageIndex, int pageSize, int totalCount)        {            TotalCount = totalCount;            TotalPages = TotalCount / pageSize;            if (TotalCount % pageSize > 0)                TotalPages++;            this.PageSize = pageSize;            this.PageIndex = pageIndex;            this.AddRange(source);        }        public int PageIndex { get; PRivate set; }        public int PageSize { get; private set; }        public int TotalCount { get; private set; }        public int TotalPages { get; private set; }        public bool HasPreviousPage        {            get { return (PageIndex > 0); }        }        public bool HasNextPage        {            get { return (PageIndex + 1 < TotalPages); }        }    }

转换失败,AutoMapper可不认识PagedList

 [TestMethod]        public void MapTest2()        {            Mapper.CreateMap<User, UserViewModel>();            var userList = new List<User>()            {                new User() {Name = "Name1", UserId = "UserId1"},                new User() {Name = "Name2", UserId = "UserId2"},                new User() {Name = "Name3", UserId = "UserId3"},                new User() {Name = "Name4", UserId = "UserId4"},                new User() {Name = "Name5", UserId = "UserId5"},                new User() {Name = "Name6", UserId = "UserId6"},                new User() {Name = "Name7", UserId = "UserId7"},            };            var pagedList = new PagedList<User>(userList, 0, 5);                        Mapper.Map<PagedList<User>, PagedList<UserViewModel>>(pagedList);//Exception                    }

解决方案

 /// <summary>    /// The collection extensions.    /// </summary>    public static class ObjectExtensions    {        private static readonly MethodInfo mapMethod;        private static readonly ConcurrentDictionary<Tuple<Type, Type>, Tuple<MethodInfo, Type>> methodsMapper = new ConcurrentDictionary<Tuple<Type, Type>, Tuple<MethodInfo, Type>>();        static ObjectExtensions()        {            mapMethod = (typeof(Mapper)).GetMethods().FirstOrDefault(_ => _.Name == "Map" && _.GetParameters().Length == 1);        }        public static T MapTo<T>(this IPagedList tList) where T : class        {            var totalCount = tList.TotalCount;            var pageIndex = tList.PageIndex;            var pageSize = tList.PageSize;            var t = methodsMapper.GetOrAdd(new Tuple<Type, Type>(tList.GetType(), typeof(T)), _ =>            {                var targetGenericArguments = typeof(T).GenericTypeArguments[0];                var targetGenericArgumentsIEnumerableType = typeof(IEnumerable<>).MakeGenericType(targetGenericArguments);                return new Tuple<MethodInfo, Type>(mapMethod.MakeGenericMethod(targetGenericArgumentsIEnumerableType),                    typeof(PagedList<>).MakeGenericType(targetGenericArguments));            });            var rtn2 = t.Item1.Invoke(null, new object[] { tList });            var o2 = Activator.CreateInstance(t.Item2, rtn2, pageIndex, pageSize, totalCount) as T;            return o2;        }        public static T MapTo<T>(this object o) where T : class        {            //way1            //var mapMethod = (typeof(Mapper)).GetMethods().FirstOrDefault(_ => _.Name == "Map" && _.GetParameters().Length == 1 && _.GetGenericArguments().Length == 2 );            //var m2 =  mapMethod.MakeGenericMethod(o.GetType(), typeof (T));            //return m2.Invoke(null, new[] { o }) as T;            //way2            return Mapper.Map<T>(o);        }        public static void MapTo<S,T>(this S o,T t) where T : class        {            Mapper.Map(o,t);        }    }

测试通过

[TestMethod]        public void MapTest2()        {            Mapper.CreateMap<User, UserViewModel>();            var userList = new List<User>()            {                new User() {Name = "Name1", UserId = "UserId1"},                new User() {Name = "Name2", UserId = "UserId2"},                new User() {Name = "Name3", UserId = "UserId3"},                new User() {Name = "Name4", UserId = "UserId4"},                new User() {Name = "Name5", UserId = "UserId5"},                new User() {Name = "Name6", UserId = "UserId6"},                new User() {Name = "Name7", UserId = "UserId7"},            };            var pagedList = new PagedList<User>(userList, 0, 5);            var vmPagedList = pagedList.MapTo<PagedList<UserViewModel>>();            Assert.IsTrue(vmPagedList.TotalPages == 2                 && vmPagedList.PageSize == 5                && vmPagedList.PageIndex == 0                );        }

总结

运行时动态获取泛型参数并执行Mapper.Map<IEnumerable<TSource>, IEnumerable<TDestination>>

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表