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模板的按照规则代码生成模板还在进一步开发中,敬请期待。

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

  • 相关阅读:
    mysql随机数
    限制IP注册到Eureka
    Java日期格式化(DateFormat类和SimpleDateFormat类)
    直播类APP功能及技术难点(转)
    【转】Java之WeakReference与SoftReference使用讲解
    【转】android适配各种分辨率的问题
    国内市场上 Android 手机屏幕分辨率的比例情况如何?
    [转]mongodb与mysql相比的优缺点
    [转]一致性哈希算法及其在分布式系统中的应用
    [转]java byte 数据类型(基础)
  • 原文地址:https://www.cnblogs.com/whitewolf/p/AgileMapper1.html
Copyright © 2011-2022 走看看