Green.AgileMapper新增-Green.ObjectPickUper(do到dto对象的默认抽取)

     Green.AgileMapper意在处理领域驱动开发中对象之间的Mapper(如果你还不了解Green.AgileMapper,从这里开始Green.AgileMapper开源项目的使用(1) 和Green.AgileMapper项目(2)-新增DO和DTO代码生成,项目地址:CodePlexhttp://agilemapper.codeplex.com/),本项目在后期会针对领域建模提供设计时候支持,利用EF和NHibernate作为底层ORM框架产生自己的领域框架,在设计时才会采用这些组件。

    在我们的领域驱动开发中,DomainObject(领域对象)是一个自然oo对象,存在许多现实世界的关系关联,在我们的View端一个View却可能需要数据并不是所有关联。经常除非特殊的UI模式,我们ViewObject往往都会被弱化,而利用Data Transfer Object代替。我们的dto从do抽取大多时候都是将do 单一Object平面化,对于级联删除更新的集合抽取,非级联集合放弃。Green.ObjectPickUper就是一种由do抽取dto的实现策略,产生符合Green.AgileMapper 映射规则的dto对象。对象抽取可能存在多样性,这里只是实现了默认抽取规则,可能不能满足你的需求,你不需要急,因为在这里采用了策略模式来满足不同抽取算法的需求(ObjectPickUperBase),Green.ObjectPickUper并不依赖Green.AgileMapper你可以自由抽取。

  在Green.ObjectPickUper中利用了CodeDom实现代码生成,所以可以支持多语言(如果你还不了解CodeDom可以看这里代码生成技术-目录中CodeDom篇)。

 

我们看看单元测试看看Green.ObjectPickUper的简洁书写:

测试do对象仍是原对象StudentDo,参考CodePlex http://agilemapper.codeplex.com/

[TestMethod] 
      public void ObjectPickUper_GenCode_Test() 
      { 
          ObjectPickUperManager.Instance.IsSOAObject = false; 
          var str = ObjectPickUperManager.Instance.PickUp<StudenDo>("DTO"); 
          var str1 = ObjectPickUperManager.Instance.PickUp<ContactWay>("DTO"); 
          var str2 = ObjectPickUperManager.Instance.PickUp<KeyValuePair>("DTO"); 

          Assert.IsTrue(!string.IsNullOrEmpty(str)); 

          //验证编译是否正确 
          CompilerParameters option = new CompilerParameters(); 
          option.GenerateExecutable = false; 
          option.GenerateInMemory = true; 
          option.IncludeDebugInformation = false; 
          option.ReferencedAssemblies.Add("System.dll"); 
          option.ReferencedAssemblies.Add(typeof(System.Linq.IQueryable).Assembly.Location); 
          option.ReferencedAssemblies.Add(typeof(StudenDo).Assembly.Location); 
          option.ReferencedAssemblies.Add(typeof(Green.AgileMapper.CollectionMappingAttribute).Assembly.Location); 

          var result = CodeDomProvider.CreateProvider("c#").CompileAssemblyFromSource(option, str, str1, str2); 
          var assembly = result.CompiledAssembly; 
          Assert.IsFalse(result.Errors.HasErrors, "编译错误"); 
      }

这里采用CodeDom动态编译,查看是否存在编译错误。 

生成dto:

namespace Green.AgileMapper.Test 

    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    [System.SerializableAttribute()] 
    public class StudenDoDTO : System.ComponentModel.INotifyPropertyChanged, System.ICloneable 
    { 
        private int _ID; 
        private Green.AgileMapper.Test.Sex _Sex; 
        private System.Collections.Generic.List<System.String> _CourseIds; 
        private string _AddressCountry; 
        private string _AddressProvince; 
        private string _AddressStreet; 
        private string _AddressParticular; 
        private Green.AgileMapper.Test.ContactWayDTO _ContactWay; 
        private System.Collections.Generic.List<Green.AgileMapper.Test.KeyValuePairDTO> _Propertys; 
        public int ID 
        { 
            get 
            { 
                return this._ID; 
            } 
            set 
            { 
                if ((this._ID != value)) 
                { 
                    this._ID = value; 
                    this.OnNotifyPropertyChanged("ID"); 
                } 
            } 
        } 
        public Green.AgileMapper.Test.Sex Sex 
        { 
            get 
            { 
                return this._Sex; 
            } 
            set 
            { 
                if ((this._Sex != value)) 
                { 
                    this._Sex = value; 
                    this.OnNotifyPropertyChanged("Sex"); 
                } 
            } 
        } 
        [Green.AgileMapper.CollectionMappingAttribute(Name="CourseIds", IsConvertTo=true, IsConvertFrom=true, IsDeleteNotInFromItem=true)] 
        public System.Collections.Generic.List<System.String> CourseIds 
        { 
            get 
            { 
                return this._CourseIds; 
            } 
            set 
            { 
                if ((this._CourseIds != value)) 
                { 
                    this._CourseIds = value; 
                    this.OnNotifyPropertyChanged("CourseIds"); 
                } 
            } 
        } 
        [Green.AgileMapper.MappingAttribute(Name="Address.Country", IsConvertTo=true, IsConvertFrom=true)] 
        public string AddressCountry 
        { 
            get 
            { 
                return this._AddressCountry; 
            } 
            set 
            { 
                if ((this._AddressCountry != value)) 
                { 
                    this._AddressCountry = value; 
                    this.OnNotifyPropertyChanged("AddressCountry"); 
                } 
            } 
        } 
        [Green.AgileMapper.MappingAttribute(Name="Address.Province", IsConvertTo=true, IsConvertFrom=true)] 
        public string AddressProvince 
        { 
            get 
            { 
                return this._AddressProvince; 
            } 
            set 
            { 
                if ((this._AddressProvince != value)) 
                { 
                    this._AddressProvince = value; 
                    this.OnNotifyPropertyChanged("AddressProvince"); 
                } 
            } 
        } 
        [Green.AgileMapper.MappingAttribute(Name="Address.Street", IsConvertTo=true, IsConvertFrom=true)] 
        public string AddressStreet 
        { 
            get 
            { 
                return this._AddressStreet; 
            } 
            set 
            { 
                if ((this._AddressStreet != value)) 
                { 
                    this._AddressStreet = value; 
                    this.OnNotifyPropertyChanged("AddressStreet"); 
                } 
            } 
        } 
        [Green.AgileMapper.MappingAttribute(Name="Address.Particular", IsConvertTo=true, IsConvertFrom=true)] 
        public string AddressParticular 
        { 
            get 
            { 
                return this._AddressParticular; 
            } 
            set 
            { 
                if ((this._AddressParticular != value)) 
                { 
                    this._AddressParticular = value; 
                    this.OnNotifyPropertyChanged("AddressParticular"); 
                } 
            } 
        } 
        [Green.AgileMapper.ObjectMappingAttribute(Name="ContactWay")] 
        public Green.AgileMapper.Test.ContactWayDTO ContactWay 
        { 
            get 
            { 
                return this._ContactWay; 
            } 
            set 
            { 
                if ((this._ContactWay != value)) 
                { 
                    this._ContactWay = value; 
                    this.OnNotifyPropertyChanged("ContactWay"); 
                } 
            } 
        } 
        [Green.AgileMapper.CollectionMappingAttribute(Name="Propertys", IsConvertTo=true, IsConvertFrom=true, IsDeleteNotInFromItem=true, EqualExpression=null)] 
        public System.Collections.Generic.List<Green.AgileMapper.Test.KeyValuePairDTO> Propertys 
        { 
            get 
            { 
                return this._Propertys; 
            } 
            set 
            { 
                if ((this._Propertys != value)) 
                { 
                    this._Propertys = value; 
                    this.OnNotifyPropertyChanged("Propertys"); 
                } 
            } 
        } 
        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; 
        public void OnNotifyPropertyChanged(string property) 
        { 
            if ((this.PropertyChanged != null)) 
            { 
                this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(property)); 
            } 
        } 
        public object Clone() 
        { 
            StudenDoDTO cloneObj; 
            cloneObj = new StudenDoDTO(); 
            cloneObj._ID = this.ID; 
            cloneObj._Sex = this.Sex; 
            System.Collections.Generic.List<System.String> CourseIdsList; 
            CourseIdsList = new System.Collections.Generic.List<System.String>(); 
            if ((this.CourseIds != null)) 
            { 
                int i; 
                for (i = 0; (i < this.CourseIds.Count); i = (i + 1)) 
                { 
                    CourseIdsList.Add(this.CourseIds[i]); 
                } 
            } 
            cloneObj._CourseIds = CourseIdsList; 
            cloneObj._AddressCountry = this.AddressCountry; 
            cloneObj._AddressProvince = this.AddressProvince; 
            cloneObj._AddressStreet = this.AddressStreet; 
            cloneObj._AddressParticular = this.AddressParticular; 
            cloneObj._ContactWay = ((Green.AgileMapper.Test.ContactWayDTO)(this.ContactWay.Clone())); 
            System.Collections.Generic.List<Green.AgileMapper.Test.KeyValuePairDTO> PropertysList; 
            PropertysList = new System.Collections.Generic.List<Green.AgileMapper.Test.KeyValuePairDTO>(); 
            if ((this.Propertys != null)) 
            { 
                int i; 
                for (i = 0; (i < this.Propertys.Count); i = (i + 1)) 
                { 
                    PropertysList.Add(((Green.AgileMapper.Test.KeyValuePairDTO)(this.Propertys[i].Clone()))); 
                } 
            } 
            cloneObj._Propertys = PropertysList; 
            return cloneObj; 
        } 
    } 
}

源代码参加:CodePlex http://agilemapper.codeplex.com/ 

其他相关博文:

1:Green.AgileMapper开源项目的使用(1)

2:Green.AgileMapper项目(2)-新增DO和DTO代码生成

3:代码生成技术-目录

作者:破  狼 
出处:http://www.cnblogs.com/whitewolf/ 
本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。该文章也同时发布在我的独立博客中-个人独立博客博客园--破狼51CTO--破狼。http://www.cnblogs.com/whitewolf/archive/2012/04/05/ObjectPickUper.html

时间: 2025-01-21 11:43:42

Green.AgileMapper新增-Green.ObjectPickUper(do到dto对象的默认抽取)的相关文章

Green.AgileMapper开源项目的使用(1)

     在架构设计中,利用领域驱动开发时,涉及到do(领域对象)和dto(数据传输对象)的相互装换匹配,这段代码简单但是重复频率太多,写得我很冒火(我有个职责是wcf SOA包装),我是个不喜欢重复劳动的懒人,我在网上搜索等到很多实体匹配的框架EmitMapper,AutoMapper等,但是他们都不能满足dto和do的对象的按规则匹配包装.最后我只得花了半个小时写了一个简单的代码生成器,完成了我的任务.但是事后总觉得不爽,于是有了写下这个AgileMapper框架来适应领域开发中的po,do

Green.AgileMapper项目(2)-新增DO和DTO代码生成

     如果你还不了解Green.AgileMapper的用意,作用请先一步到上篇Green.AgileMapper开源项目的使用,如果你觉得运行时(Runtime)的Mapper效率存在问题,在这个版本中有了更新,新增了C#直接代码的生成,这里的生成都已3.0后的扩展方法实现,你可以很方便的一句代码实现两者的转化.     代码生成我本想利用T4模板,但是由于我们的项目IDE版本是VS2008,对于T4的参数传递支持还不是很友好,你可能说用AppDomain.SetData,或者CallCo

ASP.NET 2.0数据操作教程之十九:给编辑和新增界面增加验证控件

返回"ASP.NET 2.0数据教程目录" 译注:Scott Mitchell写的46篇(现在发布了前15篇)ASP.NET2.0教程系列第 19篇译文,原文尚未发布,Word文档可以在这里下载中英混排版本,这里下载中 文版本 目录 简介 一.从<Examining the Events Associated with Inserting, Updating, and Deleting >中复制代码 二.将绑定列 转换为模板列 三.为GridView的项编辑模板(EditI

treeview和xml-C# winform中treeView我想新增一个节点,同时这个节点对应的新增一个对象

问题描述 C# winform中treeView我想新增一个节点,同时这个节点对应的新增一个对象 C# winform treeView,2级,第一级是控制卡,控制卡的参数是IP,右边的tabpage可以对参数赋值,第二级是控制卡下面是素材,素材也有几个参数的,tabpage也可以对参数赋值,我想怎么新增一个节点的同时新增一个对象,比如新增控制卡1的节点,就新增一个控制卡1的对象,然后控制卡1的对象下面可以增加素材,我的想法是用一个list,但是不知道类怎么定义,有大牛吗?当然了定义之后可以写在

与众不同 windows phone (40) - 8.0 媒体: 音乐中心的新增功能, 图片中心的新增功能, 后台音乐播放的新增功能

原文:与众不同 windows phone (40) - 8.0 媒体: 音乐中心的新增功能, 图片中心的新增功能, 后台音乐播放的新增功能 [源码下载] 与众不同 windows phone (40) - 8.0 媒体: 音乐中心的新增功能, 图片中心的新增功能, 后台音乐播放的新增功能 作者:webabcd 介绍与众不同 windows phone 8.0 之 媒体 添加音乐到音乐中心,从音乐中心删除音乐 与图片中心相关的新增功能 BackgroundAudioPlayer 的新增功能 示例

领域驱动设计系列(2)浅析VO、DTO、DO、PO的概念、区别和用处

转自:http://kb.cnblogs.com/page/522348/ 上一篇文章作为一个引子,说明了领域驱动设计的优势,从本篇文章开始,笔者将会结合自己的实际经验,谈及领域驱动设计的应用.本篇文章主要讨论一下我们经常会用到的一些对象:VO.DTO.DO和PO. 由于不同的项目和开发人员有不同的命名习惯,这里我首先对上述的概念进行一个简单描述,名字只是个标识,我们重点关注其概念: 概念: VO(View Object):视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据封装起

在ASP.NET 2.0中操作数据之十九:给编辑和新增界面增加验证控件_自学过程

导言 在前面三节的示例中,GridView和DetailsView控件使用的是绑定列和CheckBoxField(绑定GridView和DetailsView时,通过智能标记可以令VS根据数据库自动增加对应的类型).当编辑GridView或者DetailsView中的一行时,非只读属性的绑定列将自动转为textbox,以便用户修改现有的数据.同样地,当在DetailsView控件中新增记录时,InsertVisible属性为true(默认值)的绑定列会呈现出空的textbox,以接受用户输入.C

js操作table元素实现表格行列新增、删除技巧总结_javascript技巧

本文实例讲述了js操作table元素实现表格行列新增.删除的方法.分享给大家供大家参考,具体如下: /************ TableTool.js ****************************************************************************************************************** **********************************************************

grails在有数据的表中新增字段,如何为新增字段赋初值?

问题描述 有没有人做过对有数据的表中增加一字段,通过grails的domain对应新增字段的属性设定数据库表的默认值,怎么设置.我这边不论怎么设置,新增的domain属性,在有数据的表中其字段的值永远都是(null),可我想要我设定的默认值我该怎么做?如某domain中定义新增的属性intsynDelType=0;数据库对应的表中列syn_del_type的值一直都是(null)注:是在有数据的表,新加属性重新启动工程对新加列赋初值,不是在new或者update的时候赋初值因为新加这个字段,就是