用过MonoRail的朋友应该知道它提供的对象成员数据绑定功能非常方便,通过标记参数属性或方法就可以自动把提交回来的数据和对象成员进行绑定;有了这些方便的功能的确可以节省大量的set代码。不过这些功能只是MonoRail提供,于是实现类似的功能方便自己开发。
实现目标:
可以灵活方便地实现数据绑定。
OrderSearch search = FormContext.BindObject<OrderSearch>();
Orders order = FormContext.BindObject<Orders>("order");
制定规则和约束
首先确定WEB提交的数据和成员属性的映射关系,可以通过名称约定的方式:
<input id="Text1" name="companyname" type="text" />
xxxx.LastName、xxxx_LastName或xxxxLastName等。在绑过程可以指定前缀进行对象成员的绑定;不过在webForm控件的Name是asp.net生成的,在关系分析上就相对复杂些。
类型转换接口的定义
因为转换的情况是很难确定;除了。NET的基础类型外实际应用中还会存在其他转换方式,如:HttpPostedFile到byte[],序列化String到Object等。因此制定转换接口就可以方便实现可扩展和可配置。
public interface IStringConverter
{
object ConvertTo(string value, out bool succeeded);
}
由于Web提供的数据大部份是以string的方式提供,因此定义一个基于string转换描述。基于接口的实也很简单:
public class ToSbyte :IStringConverter
{
#region IStringConverter 成员
object IStringConverter.ConvertTo(string value, out bool succeeded)
{
sbyte nvalue;
succeeded = sbyte.TryParse(value, out nvalue);
return nvalue;
}
#endregion
}
IStringConverter工厂的实现
由于转换情况的不确定性,因此通过工厂的方式来达到代码对外的封闭性和良好的扩展性。可以通过目标类型来获取相关转换实例,在.NET中IDictionary就能够达到应用的要求。
static IDictionary<Type, IStringConverter> mConverters;
public static IDictionary<Type, IStringConverter> Converters
{
get
{
if (mConverters == null)
{
lock (typeof(ConverterFactory))
{
OnInit();
}
}
return mConverters;
}
}
static void OnInit()
{
if (mConverters != null)
return;
mConverters = new Dictionary<Type, IStringConverter>();
mConverters.Add(typeof(byte), new ToByte());
LoadConfig();
}