如果你还不了解Green.AgileMapper的用意,作用请先一步到上篇Green.AgileMapper开源项目的使用,如果你觉得运行时(Runtime)的Mapper效率存在问题,在这个版本中有了更新,新增了C#直接代码的生成,这里的生成都已3.0后的扩展方法实现,你可以很方便的一句代码实现两者的转化。

代码生成我本想利用T4模板,但是由于我们的项目IDE版本是VS2008,对于T4的参数传递支持还不是很友好,你可能说用AppDomain.SetData,或者CallContext.LogicalSetData,但是可惜我们的饿MappingRule是不可序列化的,所以最后我只得采用了字符串拼接最笨的办法,为了应对生成策略不同,在这里我们加入了策略模式来应付,来看看代码结构吧:

在这里只支持对do的二级属性映射为dto的平面属性,全部针对IMappingRule生成代码,在这里为了生成合法的代码而非表达式,对以前的表达式进行了重新的标准约定,在代码注释。以及对上个版本的List转换进行了多次重载,主要为了满足DTo到DO对象的特殊要求,因为我们在领域开发存储DTO的时候都是需要先取出DO对象在根据DTO在DO对象的基础上进行修改,以便ORM领域框架或者UOW的跟踪记录。

下面看看任然是上个测试类模型的代码生成(在这里测试DO,DTO类进行了重构为了更全面的测试,具体请看CodePlex http://agilemapper.codeplex.com/代码):

StudenDostu=newStudenDo() { ID=1, Name="test1", Sex=Sex.女, Address=newAddress() { Country="中国", Province="四川", Street="高新区" }, CourseIds=newList<string>(){"1","2","3"}, Propertys=newList<KeyValuePair>(){newKeyValuePair(){Key="1",Value="1"}}, ContactWay=newContactWay() { Phone="1111111111111111", Email="xxxx@12f", QQ="7889789999889" } }; Func<StudenDo,StudenDo,bool>fun=(f,j)=&gt;f.ID==j.ID; vars=fun.ToString(); varmapper=ObjectMapperManager.Default.GetMapper<StudenDto,StudenDo>(); mapper.AgileMapperTemplateStrategy.DefaultEqualExpression="{0}.ID=={1}.ID&&{1}.ID!=0"; varstr1=mapper.CodeGenerator(); System.IO.File.Delete(@"E:\Project\OpenSource\AgileMapper\AgileMappper.Test\CodeTemplate.Test\1.cs"); System.IO.File.AppendAllText(@"E:\Project\OpenSource\AgileMapper\AgileMappper.Test\CodeTemplate.Test\1.cs",str1); varmapper1=ObjectMapperManager.Default.GetMapper<ContactWayDto,ContactWay>(); str1=mapper1.CodeGenerator(); System.IO.File.Delete(@"E:\Project\OpenSource\AgileMapper\AgileMappper.Test\CodeTemplate.Test\2.cs"); System.IO.File.AppendAllText(@"E:\Project\OpenSource\AgileMapper\AgileMappper.Test\CodeTemplate.Test\2.cs",str1); varmapper2=ObjectMapperManager.Default.GetMapper<KeyValuePairDto,KeyValuePair>(); str1=mapper2.CodeGenerator(); System.IO.File.Delete(@"E:\Project\OpenSource\AgileMapper\AgileMappper.Test\CodeTemplate.Test\3.cs"); System.IO.File.AppendAllText(@"E:\Project\OpenSource\AgileMapper\AgileMappper.Test\CodeTemplate.Test\3.cs",str1);

最后的生成文件:

1.cs: usingSystem; usingSystem.Linq; usingSystem.Data; usingSystem.Collections.Generic; namespaceGreen.AgileMapper { publicstaticpartialclassAgileMapperMapping { ///<summary> ///Green.AgileMapper.Test.StudenDtoWarpfromObjGreen.AgileMapper.Test.StudenDo; ///</summary> ///<paramname="domainObj">Green.AgileMapper.Test.StudenDo</param> ///<returns>Green.AgileMapper.Test.StudenDto</returns> publicstaticGreen.AgileMapper.Test.StudenDtoWarp(thisGreen.AgileMapper.Test.StudenDodomainObj) { varfromObj=newGreen.AgileMapper.Test.StudenDto(); fromObj.ID=domainObj.ID; fromObj.Name=domainObj.Name; fromObj.Sex=domainObj.Sex; if(domainObj.Address!=null) { fromObj.Country=domainObj.Address.Country; fromObj.Province=domainObj.Address.Province; } fromObj.Particular=domainObj.Address.Country+"国籍"+domainObj.Address.Province+"省"; fromObj.FirstPropertyKey=domainObj.Propertys[0].Key; if(domainObj.ContactWay!=null) { fromObj.ContactWay=domainObj.ContactWay.Warp(); } if(domainObj.CourseIds!=null) { fromObj.CourseIds=newList<System.String>(); foreach(varitem_CourseIdsindomainObj.CourseIds) { fromObj.CourseIds.Add(item_CourseIds); } } if(domainObj.Propertys!=null) { fromObj.Propertys=domainObj.Propertys.Warp(); } returnfromObj; } ///<summary> ///Green.AgileMapper.Test.StudenDtoWarpdomainObjGreen.AgileMapper.Test.StudenDo; ///</summary> ///<paramname="domainObj">Green.AgileMapper.Test.StudenDo</param> ///<returns>fromObj</returns> publicstaticvoidWarp(thisGreen.AgileMapper.Test.StudenDtofromObj,Green.AgileMapper.Test.StudenDodomainObj) { if(fromObj==null) { return; } if(domainObj==null) { domainObj=newGreen.AgileMapper.Test.StudenDo(); } domainObj.ID=fromObj.ID; domainObj.Name=fromObj.Name; domainObj.Sex=fromObj.Sex; if(domainObj.Address==null) { domainObj.Address=newGreen.AgileMapper.Test.Address(); } domainObj.Address.Country=fromObj.Country; domainObj.Address.Province=fromObj.Province; if(domainObj.ContactWay==null) { domainObj.ContactWay=newGreen.AgileMapper.Test.ContactWay(); } fromObj.ContactWay.Warp(domainObj.ContactWay); if(fromObj.CourseIds!=null) { if(domainObj.CourseIds==null) { domainObj.CourseIds=newList<System.String>(); } domainObj.CourseIds.Clear(); foreach(varitem_CourseIdsinfromObj.CourseIds) { domainObj.CourseIds.Add(item_CourseIds); } } if(fromObj.Propertys!=null) { if(domainObj.Propertys==null) { domainObj.Propertys=newList<Green.AgileMapper.Test.KeyValuePair>(); } fromObj.Propertys.Warp(domainObj.Propertys,(fromObjItem,domainObjItem)=&gt;fromObjItem.Key==domainObjItem.Key,true); } } ///<summary> ///Green.AgileMapper.Test.StudenDtocollectionWarpfromObjGreen.AgileMapper.Test.StudenDocollection; ///</summary> ///<paramname="form">Green.AgileMapper.Test.StudenDtocollection</param> ///<paramname="domainObj">Green.AgileMapper.Test.StudenDocollection</param> publicstaticList<Green.AgileMapper.Test.StudenDto>Warp(thisIList<Green.AgileMapper.Test.StudenDo>domainObj) { List<Green.AgileMapper.Test.StudenDto>froms=newList<Green.AgileMapper.Test.StudenDto>(); domainObj.ToList().ForEach(t=&gt; { froms.Add(Warp(t)); }); returnfroms; } ///<summary> ///Green.AgileMapper.Test.StudenDtocollectionWarpdomainObjGreen.AgileMapper.Test.StudenDocollection; ///</summary> ///<paramname="fromObj">Green.AgileMapper.Test.StudenDtocollection</param> ///<paramname="domainObj">Green.AgileMapper.Test.StudenDocollection</param> publicstaticvoidWarp(thisIList<Green.AgileMapper.Test.StudenDto>fromObj,IList<Green.AgileMapper.Test.StudenDo>domainObj) { fromObj.Warp(domainObj,(fromObjItem,domainObjItem)=&gt;fromObjItem.ID==domainObjItem.ID&&domainObjItem.ID!=0,false); } ///<summary> ///Green.AgileMapper.Test.StudenDtocollectionWarpdomainObjGreen.AgileMapper.Test.StudenDocollection; ///</summary> ///<paramname="fromObj">Green.AgileMapper.Test.StudenDtocollection</param> ///<paramname="domainObj">Green.AgileMapper.Test.StudenDocollection</param> ///<paramname="isDeleteNotInFromItem">DeletetheitemthatnotinFromcollection</param> publicstaticvoidWarp(thisIList<Green.AgileMapper.Test.StudenDto>fromObj,IList<Green.AgileMapper.Test.StudenDo>domainObj,boolisDeleteNotInFromItem) { fromObj.Warp(domainObj,(fromObjItem,domainObjItem)=&gt;fromObjItem.ID==domainObjItem.ID&&domainObjItem.ID!=0,isDeleteNotInFromItem); } ///<summary> ///Green.AgileMapper.Test.StudenDtocollectionWarpdomainObjGreen.AgileMapper.Test.StudenDocollection; ///</summary> ///<paramname="fromObj">Green.AgileMapper.Test.StudenDtocollection</param> ///<paramname="domainObj">Green.AgileMapper.Test.StudenDocollection</param> ///<paramname="equalPredicate">thefromitemequaltoitemexpression</param> publicstaticvoidWarp(thisIList<Green.AgileMapper.Test.StudenDto>fromObj,IList<Green.AgileMapper.Test.StudenDo>domainObj,Func<Green.AgileMapper.Test.StudenDto,Green.AgileMapper.Test.StudenDo,bool>equalPredicate) { fromObj.Warp(domainObj,equalPredicate,false); } ///<summary> ///Green.AgileMapper.Test.StudenDtocollectionWarpdomainObjGreen.AgileMapper.Test.StudenDocollection; ///</summary> ///<paramname="fromObj">Green.AgileMapper.Test.StudenDtocollection</param> ///<paramname="domainObj">Green.AgileMapper.Test.StudenDocollection</param> ///<paramname="equalPredicate">thefromitemequaltoitemexpression</param> ///<paramname="isDeleteNotInFromItem">DeletetheitemthatnotinFromcollection</param> publicstaticvoidWarp(thisIList<Green.AgileMapper.Test.StudenDto>fromObj,IList<Green.AgileMapper.Test.StudenDo>domainObj,Func<Green.AgileMapper.Test.StudenDto,Green.AgileMapper.Test.StudenDo,bool>equalPredicate,boolisDeleteNotInFromItem) { if(fromObj==null) { return; } if(domainObj==null) { domainObj=newList<Green.AgileMapper.Test.StudenDo>(); } fromObj.ToList().ForEach(fromObjItem=&gt; { Green.AgileMapper.Test.StudenDotoItem=default(Green.AgileMapper.Test.StudenDo); if(equalPredicate!=null) { toItem=domainObj.SingleOrDefault(domainObjItem=&gt;equalPredicate(fromObjItem,domainObjItem)); } if(toItem==null) { toItem=newGreen.AgileMapper.Test.StudenDo(); domainObj.Add(toItem); } Warp(fromObjItem,toItem); }); if(isDeleteNotInFromItem) { domainObj.Where(domainObjItem=&gt;fromObj.FirstOrDefault(fromObjItem=&gt;equalPredicate(fromObjItem,domainObjItem))==null) .ToList().ForEach(t=&gt; { domainObj.Remove(t); }); } } } } 2.cs usingSystem; usingSystem.Linq; usingSystem.Data; usingSystem.Collections.Generic; namespaceGreen.AgileMapper { publicstaticpartialclassAgileMapperMapping { ///<summary> ///Green.AgileMapper.Test.ContactWayDtoWarpfromObjGreen.AgileMapper.Test.ContactWay; ///</summary> ///<paramname="domainObj">Green.AgileMapper.Test.ContactWay</param> ///<returns>Green.AgileMapper.Test.ContactWayDto</returns> publicstaticGreen.AgileMapper.Test.ContactWayDtoWarp(thisGreen.AgileMapper.Test.ContactWaydomainObj) { varfromObj=newGreen.AgileMapper.Test.ContactWayDto(); fromObj.Phone=domainObj.Phone; fromObj.Email=domainObj.Email; fromObj.QQ=domainObj.QQ; returnfromObj; } ///<summary> ///Green.AgileMapper.Test.ContactWayDtoWarpdomainObjGreen.AgileMapper.Test.ContactWay; ///</summary> ///<paramname="domainObj">Green.AgileMapper.Test.ContactWay</param> ///<returns>fromObj</returns> publicstaticvoidWarp(thisGreen.AgileMapper.Test.ContactWayDtofromObj,Green.AgileMapper.Test.ContactWaydomainObj) { if(fromObj==null) { return; } if(domainObj==null) { domainObj=newGreen.AgileMapper.Test.ContactWay(); } domainObj.Phone=fromObj.Phone; domainObj.Email=fromObj.Email; domainObj.QQ=fromObj.QQ; } ///<summary> ///Green.AgileMapper.Test.ContactWayDtocollectionWarpfromObjGreen.AgileMapper.Test.ContactWaycollection; ///</summary> ///<paramname="form">Green.AgileMapper.Test.ContactWayDtocollection</param> ///<paramname="domainObj">Green.AgileMapper.Test.ContactWaycollection</param> publicstaticList<Green.AgileMapper.Test.ContactWayDto>Warp(thisIList<Green.AgileMapper.Test.ContactWay>domainObj) { List<Green.AgileMapper.Test.ContactWayDto>froms=newList<Green.AgileMapper.Test.ContactWayDto>(); domainObj.ToList().ForEach(t=&gt; { froms.Add(Warp(t)); }); returnfroms; } ///<summary> ///Green.AgileMapper.Test.ContactWayDtocollectionWarpdomainObjGreen.AgileMapper.Test.ContactWaycollection; ///</summary> ///<paramname="fromObj">Green.AgileMapper.Test.ContactWayDtocollection</param> ///<paramname="domainObj">Green.AgileMapper.Test.ContactWaycollection</param> publicstaticvoidWarp(thisIList<Green.AgileMapper.Test.ContactWayDto>fromObj,IList<Green.AgileMapper.Test.ContactWay>domainObj) { fromObj.Warp(domainObj,(fromObjItem,domainObjItem)=&gt;fromObjItem.Equals(domainObjItem),false); } ///<summary> ///Green.AgileMapper.Test.ContactWayDtocollectionWarpdomainObjGreen.AgileMapper.Test.ContactWaycollection; ///</summary> ///<paramname="fromObj">Green.AgileMapper.Test.ContactWayDtocollection</param> ///<paramname="domainObj">Green.AgileMapper.Test.ContactWaycollection</param> ///<paramname="isDeleteNotInFromItem">DeletetheitemthatnotinFromcollection</param> publicstaticvoidWarp(thisIList<Green.AgileMapper.Test.ContactWayDto>fromObj,IList<Green.AgileMapper.Test.ContactWay>domainObj,boolisDeleteNotInFromItem) { fromObj.Warp(domainObj,(fromObjItem,domainObjItem)=&gt;fromObjItem.Equals(domainObjItem),isDeleteNotInFromItem); } ///<summary> ///Green.AgileMapper.Test.ContactWayDtocollectionWarpdomainObjGreen.AgileMapper.Test.ContactWaycollection; ///</summary> ///<paramname="fromObj">Green.AgileMapper.Test.ContactWayDtocollection</param> ///<paramname="domainObj">Green.AgileMapper.Test.ContactWaycollection</param> ///<paramname="equalPredicate">thefromitemequaltoitemexpression</param> publicstaticvoidWarp(thisIList<Green.AgileMapper.Test.ContactWayDto>fromObj,IList<Green.AgileMapper.Test.ContactWay>domainObj,Func<Green.AgileMapper.Test.ContactWayDto,Green.AgileMapper.Test.ContactWay,bool>equalPredicate) { fromObj.Warp(domainObj,equalPredicate,false); } ///<summary> ///Green.AgileMapper.Test.ContactWayDtocollectionWarpdomainObjGreen.AgileMapper.Test.ContactWaycollection; ///</summary> ///<paramname="fromObj">Green.AgileMapper.Test.ContactWayDtocollection</param> ///<paramname="domainObj">Green.AgileMapper.Test.ContactWaycollection</param> ///<paramname="equalPredicate">thefromitemequaltoitemexpression</param> ///<paramname="isDeleteNotInFromItem">DeletetheitemthatnotinFromcollection</param> publicstaticvoidWarp(thisIList<Green.AgileMapper.Test.ContactWayDto>fromObj,IList<Green.AgileMapper.Test.ContactWay>domainObj,Func<Green.AgileMapper.Test.ContactWayDto,Green.AgileMapper.Test.ContactWay,bool>equalPredicate,boolisDeleteNotInFromItem) { if(fromObj==null) { return; } if(domainObj==null) { domainObj=newList<Green.AgileMapper.Test.ContactWay>(); } fromObj.ToList().ForEach(fromObjItem=&gt; { Green.AgileMapper.Test.ContactWaytoItem=default(Green.AgileMapper.Test.ContactWay); if(equalPredicate!=null) { toItem=domainObj.SingleOrDefault(domainObjItem=&gt;equalPredicate(fromObjItem,domainObjItem)); } if(toItem==null) { toItem=newGreen.AgileMapper.Test.ContactWay(); domainObj.Add(toItem); } Warp(fromObjItem,toItem); }); if(isDeleteNotInFromItem) { domainObj.Where(domainObjItem=&gt;fromObj.FirstOrDefault(fromObjItem=&gt;equalPredicate(fromObjItem,domainObjItem))==null) .ToList().ForEach(t=&gt; { domainObj.Remove(t); }); } } } } 3.cs: usingSystem; usingSystem.Linq; usingSystem.Data; usingSystem.Collections.Generic; namespaceGreen.AgileMapper { publicstaticpartialclassAgileMapperMapping { ///<summary> ///Green.AgileMapper.Test.KeyValuePairDtoWarpfromObjGreen.AgileMapper.Test.KeyValuePair; ///</summary> ///<paramname="domainObj">Green.AgileMapper.Test.KeyValuePair</param> ///<returns>Green.AgileMapper.Test.KeyValuePairDto</returns> publicstaticGreen.AgileMapper.Test.KeyValuePairDtoWarp(thisGreen.AgileMapper.Test.KeyValuePairdomainObj) { varfromObj=newGreen.AgileMapper.Test.KeyValuePairDto(); fromObj.Key=domainObj.Key; fromObj.Value=domainObj.Value; returnfromObj; } ///<summary> ///Green.AgileMapper.Test.KeyValuePairDtoWarpdomainObjGreen.AgileMapper.Test.KeyValuePair; ///</summary> ///<paramname="domainObj">Green.AgileMapper.Test.KeyValuePair</param> ///<returns>fromObj</returns> publicstaticvoidWarp(thisGreen.AgileMapper.Test.KeyValuePairDtofromObj,Green.AgileMapper.Test.KeyValuePairdomainObj) { if(fromObj==null) { return; } if(domainObj==null) { domainObj=newGreen.AgileMapper.Test.KeyValuePair(); } domainObj.Key=fromObj.Key; domainObj.Value=fromObj.Value; } ///<summary> ///Green.AgileMapper.Test.KeyValuePairDtocollectionWarpfromObjGreen.AgileMapper.Test.KeyValuePaircollection; ///</summary> ///<paramname="form">Green.AgileMapper.Test.KeyValuePairDtocollection</param> ///<paramname="domainObj">Green.AgileMapper.Test.KeyValuePaircollection</param> publicstaticList<Green.AgileMapper.Test.KeyValuePairDto>Warp(thisIList<Green.AgileMapper.Test.KeyValuePair>domainObj) { List<Green.AgileMapper.Test.KeyValuePairDto>froms=newList<Green.AgileMapper.Test.KeyValuePairDto>(); domainObj.ToList().ForEach(t=&gt; { froms.Add(Warp(t)); }); returnfroms; } ///<summary> ///Green.AgileMapper.Test.KeyValuePairDtocollectionWarpdomainObjGreen.AgileMapper.Test.KeyValuePaircollection; ///</summary> ///<paramname="fromObj">Green.AgileMapper.Test.KeyValuePairDtocollection</param> ///<paramname="domainObj">Green.AgileMapper.Test.KeyValuePaircollection</param> publicstaticvoidWarp(thisIList<Green.AgileMapper.Test.KeyValuePairDto>fromObj,IList<Green.AgileMapper.Test.KeyValuePair>domainObj) { fromObj.Warp(domainObj,(fromObjItem,domainObjItem)=&gt;fromObjItem.Equals(domainObjItem),false); } ///<summary> ///Green.AgileMapper.Test.KeyValuePairDtocollectionWarpdomainObjGreen.AgileMapper.Test.KeyValuePaircollection; ///</summary> ///<paramname="fromObj">Green.AgileMapper.Test.KeyValuePairDtocollection</param> ///<paramname="domainObj">Green.AgileMapper.Test.KeyValuePaircollection</param> ///<paramname="isDeleteNotInFromItem">DeletetheitemthatnotinFromcollection</param> publicstaticvoidWarp(thisIList<Green.AgileMapper.Test.KeyValuePairDto>fromObj,IList<Green.AgileMapper.Test.KeyValuePair>domainObj,boolisDeleteNotInFromItem) { fromObj.Warp(domainObj,(fromObjItem,domainObjItem)=&gt;fromObjItem.Equals(domainObjItem),isDeleteNotInFromItem); } ///<summary> ///Green.AgileMapper.Test.KeyValuePairDtocollectionWarpdomainObjGreen.AgileMapper.Test.KeyValuePaircollection; ///</summary> ///<paramname="fromObj">Green.AgileMapper.Test.KeyValuePairDtocollection</param> ///<paramname="domainObj">Green.AgileMapper.Test.KeyValuePaircollection</param> ///<paramname="equalPredicate">thefromitemequaltoitemexpression</param> publicstaticvoidWarp(thisIList<Green.AgileMapper.Test.KeyValuePairDto>fromObj,IList<Green.AgileMapper.Test.KeyValuePair>domainObj,Func<Green.AgileMapper.Test.KeyValuePairDto,Green.AgileMapper.Test.KeyValuePair,bool>equalPredicate) { fromObj.Warp(domainObj,equalPredicate,false); } ///<summary> ///Green.AgileMapper.Test.KeyValuePairDtocollectionWarpdomainObjGreen.AgileMapper.Test.KeyValuePaircollection; ///</summary> ///<paramname="fromObj">Green.AgileMapper.Test.KeyValuePairDtocollection</param> ///<paramname="domainObj">Green.AgileMapper.Test.KeyValuePaircollection</param> ///<paramname="equalPredicate">thefromitemequaltoitemexpression</param> ///<paramname="isDeleteNotInFromItem">DeletetheitemthatnotinFromcollection</param> publicstaticvoidWarp(thisIList<Green.AgileMapper.Test.KeyValuePairDto>fromObj,IList<Green.AgileMapper.Test.KeyValuePair>domainObj,Func<Green.AgileMapper.Test.KeyValuePairDto,Green.AgileMapper.Test.KeyValuePair,bool>equalPredicate,boolisDeleteNotInFromItem) { if(fromObj==null) { return; } if(domainObj==null) { domainObj=newList<Green.AgileMapper.Test.KeyValuePair>(); } fromObj.ToList().ForEach(fromObjItem=&gt; { Green.AgileMapper.Test.KeyValuePairtoItem=default(Green.AgileMapper.Test.KeyValuePair); if(equalPredicate!=null) { toItem=domainObj.SingleOrDefault(domainObjItem=&gt;equalPredicate(fromObjItem,domainObjItem)); } if(toItem==null) { toItem=newGreen.AgileMapper.Test.KeyValuePair(); domainObj.Add(toItem); } Warp(fromObjItem,toItem); }); if(isDeleteNotInFromItem) { domainObj.Where(domainObjItem=&gt;fromObj.FirstOrDefault(fromObjItem=&gt;equalPredicate(fromObjItem,domainObjItem))==null) .ToList().ForEach(t=&gt; { domainObj.Remove(t); }); } } } }

在这里的代码生产后很乱并未格式化处理,需要我们在VS中自动Ctrl+K+D格式,如果你希望生成时候就帮助格式化了的话,你可以参见工具CoolFormat源代码格式化,安装工具利用CMD命令批量格式化(可以参见百度百科:http://baike.baidu.com/view/4367725.htm)。在项目暂不会考虑这块,如果你有兴趣的可以先帮助完成,谢谢。

具体请参见项目,存在任何问题或者bug可以随时给我留言,谢谢。