Problem description
A custom pagedlist is implemented in the system.
<summary>//Paged List interface//</summary> public interface ipagedlist {int Pag Eindex {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>: ILi St<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</pa ram>//<param name= "PageIndex" >page index</param>//<param name= "PageSize" >page siz E</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 s Ize</param> public pagedlist (ilist<t> source, int pageIndex, int pageSize) {Totalcou NT = 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 s ize</param>//<param name= "TotalCount" >total count</param> public pagedlist (IEnumerable& Lt 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);} } }
Conversion failed, AutoMapper don't know 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 = "UserID 5 "}, 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}
Solution Solutions
<summary>//the collection extensions. </summary> public static class Objectextensions {private static readonly MethodInfo Mapmethod; private static readonly Concurrentdictionary<tuple<type, Type>, Tuple<methodinfo, type>> MethodsMap per = 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 mapmeth od = (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); } }
Test Pass
[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 = "UserID 5 "}, 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 && V Mpagedlist.pageindex = = 0); }
Summarize
The runtime dynamically acquires generic parameters and executes mapper.map<ienumerable<tsource>, Ienumerable<tdestination>> and use Concurrentdictionary cache MethodInfo to improve performance.
AutoMapper extension methods