技术开发 频道

基于反射和属性的Builder模式实现


新的思路
 

    回想一下,现实中我们组装一台机器或者组装一部汽车的时候,经常的办法是检查产品自己的说明书,然后开始执行构造的工作。对于我们待加工的对象是否也可以考虑类似的办法呢?可以,不过可能代价比较大,比如让每个产品都自己实现一个IList<BuildStepHandler>的属性(这里BuildStepHandler是委托,它其实指向每个具体的BuildPart()方法),但这么做太麻烦。

    .NET平台有个很好的机制——“贴标签”,也就是用Attribute来表示扩展目标产品类型的创建信息,这样我们就可以完成一个非常通用的Builder类,由它“看着说明书”加工多种多样的产品。 

完成工具类型准备:
    由于读取属性一般通过反射获得,我们先做个一个新工具——AttribueHelper。
C# 
/// 获取某个类型包括指定属性的集合
public static IList<T> GetCustomAttributes<T>(Type type) where T : Attribute
{
if (type == null) throw new ArgumentNullException("type");
T[] attributes = (T[])(type.GetCustomAttributes(typeof(T), false));
return (attributes.Length == 0) ? null : new List<T>(attributes);
}

/// 获得某各类型包括指定属性的所有方法
public static IList<MethodInfo> GetMethodsWithCustomAttribute<T>(Type type) where T : Attribute
{
if (type == null) throw new ArgumentNullException("type");
MethodInfo[] methods = type.GetMethods();
if ((methods == null) || (methods.Length == 0)) return null;
IList<MethodInfo> result = new List<MethodInfo>();
foreach (MethodInfo method in methods)
if (GetMethodCustomAttributes<T>(method) != null)
result.Add(method);
return result.Count == 0 ? null : result;
}

/// 获取某个方法指定类型属性的集合
public static IList<T> GetMethodCustomAttributes<T>(MethodInfo method) where T : Attribute
{
if (method == null) throw new ArgumentNullException("method");
T[] attributes = (T[])(method.GetCustomAttributes(typeof(T), false));
return (attributes.Length == 0) ? null: new List<T>(attributes);
}

/// 获取某个方法指定类型的属性
public static T GetMethodCustomAttribute<T>(MethodInfo method) where T : Attribute
{
IList<T> attributes = GetMethodCustomAttributes<T>(method);
return (attributes == null) ? null : attributes[0];
}
0
相关文章