posts - 165,  comments - 876,  trackbacks - 41

       在实际开发过程中需要经常编写EntityUI数据交换相关代码,虽然代码并不复杂但确是一个非常烦琐的事情。为了解决这一问题所以编写一个数据绑定组件来处理这方面的事情,即减少代码编写的时也提高代码维护的方便性。

       组件类结构图:

      

 

组件主要有三个对象

       EntityDataBinder

              数据绑定对象,要用于Entity数据输出UIUI导入数据给Entity

       IPropertyMapper

成员映射描述,用于表示Entity的某个数据成员对应着相关对象的成员属性;对象的Changer属性用于描述数据输入和输入的转换方式。

       IChanger

数据转换对象,用于隔离数据输入和输出转换的实现,可以方便开发人员实现自己的转换类型方式。组件实现了基础的转换对象ChangerToStringFormatDateTimeToString等。

      

       相关实现代码

       EntityDataBinder

       public class EntityDataBinder<T> where T:new()

    {

        List<IPropertyMapper<T>> mMappers = new List<IPropertyMapper<T>>();

        public void AddMapper(IPropertyMapper<T> item)

        {

           

            mMappers.Add(item);

        }

        public void Import(T entity)

        {

            foreach (IPropertyMapper<T> item in mMappers)

            {

                item.Import(entity);

            }

        }

        public T Import()

        {

            T entity = new T();

            Import(entity);

            return entity;

        }

        public void Export(T entity)

        {

            foreach (IPropertyMapper<T> item in mMappers)

            {

                item.Export(entity);

            }

        }

        public void AddMapper(object source, string sourceproperty, string entityproperty)

        {

            AddMapper(source, sourceproperty, entityproperty, null);

        }

        public void AddMapper(object source, string sourceproperty, string entityproperty,IChanger changer)

        {

            IPropertyMapper<T> mapper;

            if (changer == null)

            {

                mapper = new PropertyMapper<T>(source, GetSProperty(source, sourceproperty), GetEProperty(entityproperty));

               

            }

            else

            {

                mapper = new PropertyMapper<T>(source, GetSProperty(source, sourceproperty), GetEProperty(entityproperty),changer);

            }

            AddMapper(mapper);

        }

     .

     }

 

       PropertyMapper

public class PropertyMapper<T> : IPropertyMapper<T>

    {

        public PropertyMapper(object source, PropertyInfo sourceproperty, PropertyInfo entityproperty)

        {

            Source = source;

            SourceProperty = sourceproperty;

            EntityProperty = entityproperty;

        }

        public PropertyMapper(object source, PropertyInfo sourceproperty, PropertyInfo entityproperty, IChanger changer)

        {

            Source = source;

            SourceProperty = sourceproperty;

            EntityProperty = entityproperty;

            Changer = changer;

        }

        #region IPropertyMapper 成员

 

        public void Import(T entity)

        {

            OnImport(entity);

        }

        public void Export(T entity)

        {

            OnExport(entity);

        }

 

      

        protected virtual void OnExport(T entity)

        {

            object value = EntityProperty.GetValue(entity, null);

            if (value == null)

                return;

             object newvalue = Changer.Export(value);

            try

            {

                SourceProperty.SetValue(Source, newvalue, null);

               

            }

            catch (Exception e)

            {

                string err = string.Format(

                    ErrorMsg.VALUE_CAST, entity.GetType(), EntityProperty, Source.GetType(), SourceProperty);

                throw (new SwitchException(err, e));

            }

           

        }

        protected virtual void OnImport(T entity)

        {

            object value = SourceProperty.GetValue(Source,null);

             object newvalue = Changer.Import(value);

            try

            {

                EntityProperty.SetValue(entity,newvalue, null);

            }

            catch (Exception e)

            {

                string err = string.Format(

                   ErrorMsg.VALUE_CAST,Source.GetType(), mSourceProperty, entity.GetType(), mEntityProperty);

                throw (new SwitchException(err, e));

            }

          

        }

            .

      }

      

IChanger

    public interface IChanger

    {

        object Export(object value);

        object Import(object value);

    }

    public class Changer:IChanger

    {

        #region IChanger 成员

 

        public virtual object Export(object value)

        {

            return value;

        }

 

        public virtual object Import(object value)

        {

            return value;

        }

 

        #endregion

    }

    public abstract class ToStringFormat : Changer

    {

        public ToStringFormat()

        {

        }

        public ToStringFormat(string format)

        {

            Format = format;

        }

        private string mFormat = "{0}";

        public string Format

        {

            get

            {

                return mFormat;

            }

            set

            {

                mFormat = value;

            }

        }

        public override object Export(object value)

        {

            return string.Format(mFormat, value);

        }

    }

 

使用例程:

            mEmployeeBinder = new HFSoft.DataSwitch.EntityDataBinder<Employees>();

          mEmployeeBinder .AddMapper(textBox1, "Text", "FirstName");

          mEmployeeBinder .AddMapper(textBox2, "Text", "LastName");

          mEmployeeBinder .AddMapper(dateTimePicker1, "Value", "BirthDate");

         //获取数据输入

              Employees emp = mEmployeeBinder.Import();

 

       组件刚刚编写完成和简单应用测试,功能还很简陋;由于数据交换过程采用反射所以性能并不理想。

posted on 2006-10-10 15:28 henry 阅读(1579) 评论(10)  编辑 收藏

FeedBack:
2006-10-10 15:59 | ∈鱼杆      
BS架构的适合吗?有点启发,经常是通过实体Entity填充UI,然后又通过UI填充实体。映射关系是否要用ViewState保存,这样我可以一开始定义和UI和Entity的关系,即使我页面有操作呢,也只有定义一次映射关系。
  回复  引用  查看    
#2楼 [楼主]
2006-10-10 16:12 | henry      
@∈鱼杆
可以用,由于asp.net是无状态其实也没有必要保存到ViewState中,使用时重新创建Binder就可以(通过子方法创建就不需要得复编写,即使放在ViewState还原也是做同样的工作),对于反映射信息可以使用缓冲保存。

以下是通过ACT测试情况比对(只供参考):
(1) 测试名称: ACTSamples: DataSwitch
测试运行名称: 数据绑定器(10成员)
测试开始时间: 2006-10-9 13:54:00
测试持续时间: 00:00:02:00
测试迭代次数: 26,228
测试说明: -
(2) 测试名称: ACTSamples: DataSwitch
测试运行名称: 硬编码(10成员)
测试开始时间: 2006-10-9 13:34:44
测试持续时间: 00:00:02:00
测试迭代次数: 27,585
测试说明: -

  回复  引用  查看    
2006-10-10 16:32 | lymph      
可以提供下载吗?有无使用方法啊?
  回复  引用  查看    
2006-10-10 16:37 | 上善若水      
数据转换,我认为应该直接依存于.Net类库的转换代码。
.Net已经提供了大量的类型转换方法了。
请参考TypeConverter类。

  回复  引用  查看    
#5楼 [楼主]
2006-10-10 16:45 | henry      
@上善若水
TypeConverter性能应该没有显式转换高。
不过Changer除了提供类型转换外,最主要是可以进行输出和输入格式制定。

@lymph
这里只是描述实现的思路,组件还在修改和测试所以没有提供下载。
  回复  引用  查看    
2006-10-10 16:50 | 上善若水      
TypeConverter是一个数据转换的基础.我没有看.Net源码,所以不好说它的性能如何,但如果你觉得它性能不够好的话,完全可以在其基础上实现你自己的数据转换器,完全可以实现输入和输出的格式制定。
你说的显示转换我不明白。
  回复  引用  查看    
#7楼 [楼主]
2006-10-10 17:12 | henry      
@上善若水
TypeConverter转换的类型应该存在一个hastTable,按道理是没有直接转换或拆箱高。
在实际应用中TypeConverter也不能满足需要才不把组件依赖于它,很多时候object<->;xml或者对象来原于一个TextBox的Text等。
有个可扩展的转换器可以灵活地做很多事件(当然这些东西都可以通过其他方式完成)
  回复  引用  查看    
2006-10-11 08:45 | 编写人生      
我觉得楼主还在犯性能和开发效率的基本错误。
更高的技术是能够理解并升华别人的东西
  回复  引用  查看    
2007-02-12 10:34 | MonkRui      
能不能把代码提供全啊,没有IPropertyMapper,请回复,谢谢。

mail:ruilei.blogs@gmail.com
  回复  引用  查看    
#10楼 [楼主]
2007-02-12 12:29 | henry      
IPropertyMapper只是个接口
看类图就知道该接口的成员信息.
  回复  引用  查看    

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2006-10-10 16:00 编辑过
 
 


<2006年10月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

寻求伯乐,限广州地区有意联系


与我联系

搜索

 

常用链接

留言簿(20)

我参加的小组

我的标签

随笔分类

最新评论

  • 1. re: JQuery实现自定义对话框
  • 你好 我是出版社的编辑,我看到你博客中的内容,感觉写的非常好,如果想把这些内容和更多的人分享,可以和我联系,把这些东西写成书。 我的邮箱:books_522008@yahoo.com.cn ...
  • --庞永庆
  • 2. re: 如何设计业务逻辑?
  • 我赞成定义,这需要丰富的应用经验。 --引用-------------------------------------------------- Ivony...: --引用------------...
  • --Kai.Ma
  • 3. re: 如何设计业务逻辑?
  • 针对LZ提出的,我们如何知道做出来的东西能满足以后的需要呢? 我自己的感觉,在满足自己目前的前提下,留一些适当的余地。 当有新的需求提出,重新检查下有无类似的代码? 如果有,而且发现重写一个新的方...
  • --思考-总结
  • 4. re: 如何设计业务逻辑?
  • 学习了

    第一种,要调整参数,感觉改起来麻烦
    第二种,感觉好很多
  • --未公布
  • 5. re: 如何设计业务逻辑?
  • 看文章,看评论,颇多收获!
  • --水言木

60天内阅读排行