zoukankan      html  css  js  c++  java
  • Green.AgileMapper开源项目的使用(1)

           在架构设计中,利用领域驱动开发时,涉及到do(领域对象)和dto(数据传输对象)的相互装换匹配,这段代码简单但是重复频率太多,写得我很冒火(我有个职责是wcf SOA包装),我是个不喜欢重复劳动的懒人,我在网上搜索等到很多实体匹配的框架EmitMapper,AutoMapper等,但是他们都不能满足dto和do的对象的按规则匹配包装。最后我只得花了半个小时写了一个简单的代码生成器,完成了我的任务。但是事后总觉得不爽,于是有了写下这个AgileMapper框架来适应领域开发中的po,do,dto,vo着一些列对象的相互包装,建立一个按规则包装的Mapper框架。项目已经完成上传于CodePlex http://agilemapper.codeplex.com/ ,目前刚成型,希望大家能够帮助测试,提出bug,或者修复。我不是很清楚开源协议,选择了一个 协议。大家可以随便使用和修改应用来满足各自的需求,但是如果有些bug修复或者好的通用的修改希望大家能够,提交供我和其他人学习共同进步,但是这不是必须的,你也可以选择保留。

           AgileMapper架构设计类图:

    AgileMapper

        在AgileMapper中支持多种MappingConfigurator(匹配管理器)都集成至MappingConfiguratorBase(MappingConfiguratorBase中拥有唯一的对象之间对于相等的默认表达式守信,针对于dto转化为do对象级联删除情况),内置了AttributeMappingConfigurator,XMLMappingConfigurator,DataRowMappingConfigurator三种匹配管理器。支持xml书写,attribute标记规则。由这些管理器根据具体标记标记方式产生一组IMappingRule(匹配规则),内置了5中匹配规则(简单,集合,表达式,对象,datarow)。

       在AgileMapper为我们提供了MappingConfiguratorBase的扩展,IMappingRule的扩展,已经多余Attribute标注的扩展CustomerMappingAttribute,已经xml的配置扩展。

    下面我们来使用AgileMapper提供的内置Mapper。

    测试预备:

    Domain Object:

    View Code
    public class StudenDo 
       { 
           public int ID 
           { 
               get
               set
           } 

           public string Name 
           { getset; } 

           public Sex Sex 
           { getset; } 

           public Address Address 
           { getset; } 

           public ContactWay ContactWay 
           { getset; } 

           public List<string> CourseIds 
           { getset; } 

           public List<KeyValuePair> Propertys 
           { getset; } 

       } 

       public class KeyValuePair 
       { 
           public string Key 
           { getset; } 

           public string Value 
           { getset; } 
       } 

       public enum Sex 
       { 
           男, 女 
       }

     

    public class ContactWay 
       { 
          public string Phone 
          { 
              get
              set
          } 

          public string Email 
          { 
              get
              set
          } 

          public string QQ 
          { 
              get
              set
          } 
       }

     

     

    public class Address 
       { 
           public string Country 
           { 
               get
               set
           } 

           public string Province 
           { getset; } 

           public string Street 
           { getset; } 

           public string Particular 
           { getset; } 
       }

     

    Dto:

    View Code
      

    public class StudenDto 
       { 
           public int ID 
           { 
               get
               set
           } 

           public string Name 
           { getset; } 

           public Sex Sex 
           { getset; } 

           [Mapping("Address.Country")] 
           public string Country 
           { 
               get
               set
           } 

           [Mapping("Address.Province")] 
           public string Province 
           { getset; } 

           // [Mapping("Address.Street")] 
           [IgnoreMapping] 
           public string Street 
           { getset; } 

           [ExpressionMapping("Address.Country +\" 国籍 \"+Address.Province +\" 省 \"")] 
           public string Particular 
           { getset; } 

           [ObjectMappingAttribute] 
           public ContactWayDto ContactWay 
           { getset; } 

           [CollectionMapping()] 
           public List<string> CourseIds 
           { getset; } 

           [CollectionMapping(EqualExpression="from.Key==to.Key",IsDeleteNotInFromItem=true)] 
           public List<KeyValuePair> Propertys 
           { getset; } 

           [ExpressionMapping("Propertys[0].Key")] 
           public string FirstPropertyKey 
           { 
               get
               set
           } 

     

    public class ContactWayDto 
        { 
            public string Phone 
            { 
                get
                set
            } 

            public string Email 
            { 
                get
                set
            } 

            public string QQ 
            { 
                get
                set
            } 
        }

    public class AddressDto 

        public string Country 
        { 
            get
            set
        } 

        public string Province 
        { getset; } 

        public string Street 
        { getset; } 

        public string Particular 
        { getset; } 
    }

     

    一:Attribute标注:

    View Code
      

    [TestMethod] 
           public void AttributeConfig_SimpleMapping_Gen() 
           { 

               StudenDo stu = new StudenDo() 
               { 
                   ID = 1
                   Name = "test1"
                   Sex = Sex.女, 
                   Address = new Address() 
                   { 
                       Country = "中国"
                       Province = "四川"
                       Street = "高新区" 
                   }, 
                   CourseIds = new List<string>() { "1""2""3" }, 
                   Propertys = new List<KeyValuePair>() { new KeyValuePair() { Key = "1", Value = "1" } }, 
                   ContactWay = new ContactWay() 
                   { 
                       Phone = "1111111111111111"
                       Email = "xxxx@12f"
                       QQ = "7889789999889" 
                   } 
               }; 

               var mapper = ObjectMapperManager.Default.GetMapper<StudenDto, StudenDo>(); 

               var dt1 = DateTime.Now; 
               var stuDto = mapper.Warp(stu); 
               var sp = DateTime.Now - dt1; 

               dt1 = DateTime.Now; 
               stuDto = mapper.Warp(stu); 
               var sp1 = DateTime.Now - dt1; 

               Assert.AreEqual(stuDto.ID, stu.ID); 
               Assert.AreEqual(stuDto.Name, stu.Name); 
               Assert.AreEqual(stuDto.Sex, stu.Sex); 
               Assert.AreEqual(stuDto.Country, stu.Address.Country); 
               Assert.AreEqual(stuDto.Province, stu.Address.Province); 
               Assert.AreEqual(stuDto.Street, null);//Ignore 
               
    //object 
               
    // Assert.AreEqual(stuDto.ContactWay,null); 
               Assert.AreEqual(stuDto.ContactWay.QQ, stu.ContactWay.QQ); 
               Assert.AreEqual(stuDto.ContactWay.Email, stu.ContactWay.Email); 
               //expression 
               Assert.AreEqual(stuDto.Particular, string.Format("{0} 国籍 {1} 省 ", stu.Address.Country, stu.Address.Province)); 
               Assert.AreEqual(stuDto.FirstPropertyKey, stu.Propertys[0].Key); 
               //collection            
               Assert.AreEqual(stuDto.CourseIds[0], stu.CourseIds[0]); 
               Assert.AreEqual(stuDto.CourseIds.Count, stu.CourseIds.Count); 

               Assert.AreEqual(stuDto.Propertys[0].Key, stu.Propertys[0].Key); 
               Assert.AreEqual(stuDto.Propertys[0].Value, stu.Propertys[0].Value); 
               Assert.AreEqual(stuDto.Propertys.Count, stu.Propertys.Count); 

               //Warp 2 
               var stuDo = new StudenDo(); 
               mapper.Warp(stuDto, stuDo); 

               Assert.AreEqual(stuDo.ID, stuDto.ID); 
               Assert.AreEqual(stuDo.Name, stuDto.Name); 
               Assert.AreEqual(stuDo.Sex, stuDto.Sex); 
               Assert.AreEqual(stuDo.Address.Country, stuDto.Country); 
               Assert.AreEqual(stuDo.Address.Province, stuDto.Province); 
               //Assert.AreEqual(stuDo.Address.Street, null);//Ignore 
               
    //object 
               Assert.AreEqual(stuDo.ContactWay.QQ, stuDto.ContactWay.QQ); 
               Assert.AreEqual(stuDo.ContactWay.Email, stuDto.ContactWay.Email); 
               //collection 

               Assert.AreEqual(stuDo.CourseIds.Count, stuDto.CourseIds.Count); 
               Assert.AreEqual(stuDo.CourseIds[0], stuDto.CourseIds[0]); 

               Assert.AreEqual(stuDo.Propertys.Count, stuDto.Propertys.Count); 
               Assert.AreEqual(stuDo.Propertys[0].Key, stuDto.Propertys[0].Key); 
               Assert.AreEqual(stuDo.Propertys[0].Value, stuDto.Propertys[0].Value); 
           } 

           [TestMethod] 
           public void AttributeConfig_SimpleMapping() 
           { 
               StudenDo stu = new StudenDo() 
               { 
                   ID = 1
                   Name = "test1"
                   Sex = Sex.女, 
                   Address = new Address() 
                   { 
                       Country = "中国"
                       Province = "四川"
                       Street = "高新区" 
                   }, 
                   CourseIds = new List<string>() { "1""2""3" }, 
                   Propertys = new List<KeyValuePair>() { new KeyValuePair() { Key = "1", Value = "1" } }, 
                   ContactWay = new ContactWay() 
                   { 
                       Phone = "1111111111111111"
                       Email = "xxxx@12f"
                       QQ = "7889789999889" 
                   } 
               }; 

               var mapper = ObjectMapperManager.Default.GetMapper(); 
               var stuDto = mapper.Warp(typeof(StudenDto), stu) as StudenDto; 

               Assert.AreEqual(stuDto.ID, stu.ID); 
               Assert.AreEqual(stuDto.Name, stu.Name); 
               Assert.AreEqual(stuDto.Sex, stu.Sex); 
               Assert.AreEqual(stuDto.Country, stu.Address.Country); 
               Assert.AreEqual(stuDto.Province, stu.Address.Province); 
               Assert.AreEqual(stuDto.Street, null);//Ignore 
               
    //object 
               Assert.AreEqual(stuDto.ContactWay.QQ, stu.ContactWay.QQ); 
               Assert.AreEqual(stuDto.ContactWay.Email, stu.ContactWay.Email); 
               //expression 
               Assert.AreEqual(stuDto.Particular, string.Format("{0} 国籍 {1} 省 ", stu.Address.Country, stu.Address.Province)); 
               //collection            
               Assert.AreEqual(stuDto.CourseIds[0], stu.CourseIds[0]); 
               Assert.AreEqual(stuDto.CourseIds.Count, stu.CourseIds.Count); 
           } 

    二:xml配置标注规则: 

    View Code
    <?xml version="1.0" encoding="utf-8" ?> 
    <AgileMapper> 
      <Extensions> 
        <Extension Name="SimpleMappingRule" Type="Green.AgileMapper.SimpleMappingRule,Green.AgileMapper"></Extension> 
        <Extension Name="ObjectMappingRule" Type="Green.AgileMapper.ObjectMappingRule,Green.AgileMapper"></Extension> 
        <Extension Name="CollectionMappingRule" Type="Green.AgileMapper.CollectionMappingRule,Green.AgileMapper"></Extension> 
        <Extension Name="ExpressionMappingRule" Type="Green.AgileMapper.ExpressionMappingRule,Green.AgileMapper"></Extension> 
      </Extensions> 
      <Mappings> 
        <Mapping FromType="AgileMapper.Test.StudenDto,AgileMapper.Test"  > 
          <SimpleMappingRule FromPoperty="Country" ToPoperty="Address.Country"></SimpleMappingRule> 
          <SimpleMappingRule FromPoperty="Province" ToPoperty="Address.Province"></SimpleMappingRule>           
          <ObjectMappingRule  FromPoperty="ContactWay" ToPoperty="ContactWay"></ObjectMappingRule> 
          <CollectionMappingRule FromPoperty="CourseIds" ToPoperty="CourseIds"></CollectionMappingRule> 
          <CollectionMappingRule FromPoperty="Propertys" ToPoperty="Propertys" EqualExpression="from.Key==to.Key" IsDeleteNotInFromItem="true"></CollectionMappingRule> 
          <ExpressionMappingRule  FromPoperty="Particular" Expression="Address.Country +Address.Province"></ExpressionMappingRule> 
          <ExpressionMappingRule  FromPoperty="FirstPropertyKey" Expression="Propertys[0].Key"></ExpressionMappingRule> 
          <Ignores> 
            <Ignore Name="Street"></Ignore> 
          </Ignores> 
        </Mapping> 
      </Mappings> 
    </AgileMapper>

    测试代码:

    View Code
      

    [TestMethod] 
            public void XMlConfig_SimpleMapping_Gen() 
            { 

                StudenDo stu = new StudenDo() 
                { 
                    ID = 1
                    Name = "test1"
                    Sex = Sex.女, 
                    Address = new Address() 
                    { 
                        Country = "中国"
                        Province = "四川"
                        Street = "高新区" 
                    }, 
                    CourseIds = new List<string>() { "1""2""3" }, 
                    Propertys = new List<KeyValuePair>() { new KeyValuePair() { Key = "1", Value = "1" } }, 
                    ContactWay = new ContactWay() 
                    { 
                        Phone = "1111111111111111"
                        Email = "xxxx@12f"
                        QQ = "7889789999889" 
                    } 
                }; 

                var mapper = ObjectMapperManager.Default.GetMapper<StudenDto, StudenDo>(new XMLMappingConfigurator(@"E:\Project\OpenSource\AgileMapper\AgileMappper.Test\XMLConfigurator\AgileMapper.xml")); 

                var stuDto = mapper.Warp(stu);           

                Assert.AreEqual(stuDto.ID, stu.ID); 
                Assert.AreEqual(stuDto.Name, stu.Name); 
                Assert.AreEqual(stuDto.Sex, stu.Sex); 
                Assert.AreEqual(stuDto.Country, stu.Address.Country); 
                Assert.AreEqual(stuDto.Province, stu.Address.Province); 
                Assert.AreEqual(stuDto.Street, null);//Ignore 
                
    //object 
                
    // Assert.AreEqual(stuDto.ContactWay,null); 
                Assert.AreEqual(stuDto.ContactWay.QQ, stu.ContactWay.QQ); 
                Assert.AreEqual(stuDto.ContactWay.Email, stu.ContactWay.Email); 
                //expression 
                Assert.AreEqual(stuDto.Particular.Replace(" """), string.Format("{0}{1}", stu.Address.Country, stu.Address.Province)); 
                Assert.AreEqual(stuDto.FirstPropertyKey, stu.Propertys[0].Key); 
                //collection            
                Assert.AreEqual(stuDto.CourseIds[0], stu.CourseIds[0]); 
                Assert.AreEqual(stuDto.CourseIds.Count, stu.CourseIds.Count); 

                Assert.AreEqual(stuDto.Propertys[0].Key, stu.Propertys[0].Key); 
                Assert.AreEqual(stuDto.Propertys[0].Value, stu.Propertys[0].Value); 
                Assert.AreEqual(stuDto.Propertys.Count, stu.Propertys.Count); 

                //Warp 2 
                var stuDo = new StudenDo(); 
                mapper.Warp(stuDto, stuDo); 

                Assert.AreEqual(stuDo.ID, stuDto.ID); 
                Assert.AreEqual(stuDo.Name, stuDto.Name); 
                Assert.AreEqual(stuDo.Sex, stuDto.Sex); 
                Assert.AreEqual(stuDo.Address.Country, stuDto.Country); 
                Assert.AreEqual(stuDo.Address.Province, stuDto.Province); 
                //Assert.AreEqual(stuDo.Address.Street, null);//Ignore 
                
    //object 
                Assert.AreEqual(stuDo.ContactWay.QQ, stuDto.ContactWay.QQ); 
                Assert.AreEqual(stuDo.ContactWay.Email, stuDto.ContactWay.Email); 
                //collection 

                Assert.AreEqual(stuDo.CourseIds.Count, stuDto.CourseIds.Count); 
                Assert.AreEqual(stuDo.CourseIds[0], stuDto.CourseIds[0]); 

                Assert.AreEqual(stuDo.Propertys.Count, stuDto.Propertys.Count); 
                Assert.AreEqual(stuDo.Propertys[0].Key, stuDto.Propertys[0].Key); 
                Assert.AreEqual(stuDo.Propertys[0].Value, stuDto.Propertys[0].Value); 
            }

    三:DataRow的测试: 

    测试预备StudentModelForDataRow:

    View Code
    public class StudentModelForDataRow 
        { 
            public int ID 
            { getset; } 

            public string Name 
            { getset; } 
        }

    测试代码: 

    View Code
    [TestMethod] 
           public void DataRowConfig_SameTable_DataRowCloneMapping() 
           { 
               DataTable dt = new DataTable(); 
               dt.Columns.AddRange(new DataColumn[] { 
                   new DataColumn("ID",typeof(int)), 
                   new DataColumn("Name",typeof(string)) 
               }); 

               var row = dt.NewRow(); 
               row[0] = 1
               row[1] = "Green"
               dt.Rows.Add(row); 

               var rowClone = dt.NewRow(); 

               var mapper = ObjectMapperManager.Default.GetMapper(new DataRowMappingConfigurator()); 
               mapper.Warp(typeof(DataRow), row, rowClone); 
               Assert.AreEqual(row[0], rowClone[0]); 
               Assert.AreEqual(row[1], rowClone[1]); 
           } 

           [TestMethod] 
           public void DataRowConfig_UnSameTable_MutipleRule_DataRowCloneMapping() 
           { 
               DataTable dt = new DataTable(); 
               dt.Columns.AddRange(new DataColumn[] { 
                   new DataColumn("ID",typeof(int)), 
                   new DataColumn("Name",typeof(string)) 
               }); 

               DataTable dt2 = new DataTable(); 
               dt2.Columns.AddRange(new DataColumn[] { 
                   new DataColumn("ID",typeof(int)), 
                   new DataColumn("Name",typeof(string)), 
                    new DataColumn("Sex",typeof(string)) 
               }); 

               var row = dt2.NewRow(); 
               row[0] = 1
               row[1] = "Green"
               row[2] = "Nan"
               dt2.Rows.Add(row); 

               var rowClone = dt.NewRow(); 

               var mapper = ObjectMapperManager.Default.GetMapper(new DataRowMappingConfigurator()); 
               mapper.Warp(row, rowClone); 
               Assert.AreEqual(row[0], rowClone[0]); 
               Assert.AreEqual(row[1], rowClone[1]); 
           } 

           [TestMethod] 
           public void DataRowConfig_UnSameTable_Not_MutipleRule_DataRowCloneMapping() 
           { 
               DataTable dt = new DataTable(); 
               dt.Columns.AddRange(new DataColumn[] { 
                   new DataColumn("ID",typeof(int)), 
                   new DataColumn("Name",typeof(string)) 
               }); 

               DataTable dt2 = new DataTable(); 
               dt2.Columns.AddRange(new DataColumn[] { 
                   new DataColumn("ID",typeof(int)), 
                   new DataColumn("Name",typeof(string)), 
                    new DataColumn("Sex",typeof(string)) 
               }); 

               var row = dt.NewRow(); 
               row[0] = 1
               row[1] = "Green"
               dt.Rows.Add(row); 

               var rowClone = dt2.NewRow(); 

               var mapper = ObjectMapperManager.Default.GetMapper(new DataRowMappingConfigurator()); 
               mapper.Warp(row, rowClone); 
               Assert.AreEqual(row[0], rowClone[0]); 
               Assert.AreEqual(row[1], rowClone[1]); 
           } 

           [TestMethod] 
           public void DataRowConfig_To_Object_CloneMapping() 
           { 
               DataTable dt = new DataTable(); 
               dt.Columns.AddRange(new DataColumn[] { 
                   new DataColumn("ID",typeof(int)), 
                   new DataColumn("Name",typeof(string)) 
               }); 

               var row = dt.NewRow(); 
               row[0] = 1
               row[1] = "Green"
               dt.Rows.Add(row); 
               StudentModelForDataRow model = new StudentModelForDataRow(); 

               var mapper = ObjectMapperManager.Default.GetMapper(new DataRowMappingConfigurator()); 
               mapper.Warp(row, model); 
               Assert.AreEqual(model.ID, row[0]); 
               Assert.AreEqual(model.Name, row[1]); 
           }

         DataRow匹配针对相同的表结构和不同表结构,以及实体类和DataRow之间的转化。 

    单元测试结果:

    QQ截图未命名

         对于xml配置的架构还没做,以及基于T4模板的按照规则代码生成模板还在进一步开发中,敬请期待。

         今天就写在这里了,欢迎大家的指正和修改,希望你的修改如果更好能通知我,给我好的建议和探讨,谢谢。

  • 相关阅读:
    CSS盒子模型
    getContextPath、getServletPath、getRequestURI、request.getRealPath的区别
    MYSQL中的CASE WHEN END AS
    单点登录的精华总结
    git&github
    June 21st 2017 Week 25th Wednesday
    June 20th 2017 Week 25th Tuesday
    June 19th 2017 Week 25th Monday
    June 18th 2017 Week 25th Sunday
    June 17th 2017 Week 24th Saturday
  • 原文地址:https://www.cnblogs.com/whitewolf/p/AgileMapper1.html
Copyright © 2011-2022 走看看