在实际开发过程中需要经常编写Entity和UI数据交换相关代码,虽然代码并不复杂但确是一个非常烦琐的事情。为了解决这一问题所以编写一个数据绑定组件来处理这方面的事情,即减少代码编写的时也提高代码维护的方便性。
组件类结构图:
组件主要有三个对象
EntityDataBinder
数据绑定对象,要用于Entity数据输出UI和UI导入数据给Entity。
IPropertyMapper
成员映射描述,用于表示Entity的某个数据成员对应着相关对象的成员属性;对象的Changer属性用于描述数据输入和输入的转换方式。
IChanger
数据转换对象,用于隔离数据输入和输出转换的实现,可以方便开发人员实现自己的转换类型方式。组件实现了基础的转换对象Changer、ToStringFormat和DateTimeToString等。
相关实现代码
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();
组件刚刚编写完成和简单应用测试,功能还很简陋;由于数据交换过程采用反射所以性能并不理想。