[转载]CMS系统模板引擎设计(4):Parameter类设计 – 氣如蘭兮長不改,心若蘭兮終不移。 – 博客园.
/// Label参数类
/// </summary>
public class Parameter
{
/// <summary>
/// 参数名
/// </summary>
public string Name { get; set; }
/// <summary>
/// 参数初始值
/// </summary>
public string Value { get; set; }
public Parameter() { }
public Parameter(string name, string value)
{
Name = name;
Value = value;
}
/// <summary>
/// 获取参数最终值(默认为初始值)
/// </summary>
/// <param name=”parameters”></param>
/// <returns></returns>
public virtual string GetValue(params string[] parameters)
{
return Value;
}
}
这是Parameter基类,那么Url等特殊的参数我设计成了子类!
{
public override string GetValue(params string[] parameters)
{
return PageCollection.GetCurrentPage().UrlPattern.GetValue(RequestUtility.Rawurl(), Name);
}
}
public class Format : Parameter
{
public override string GetValue(params string[] parameters)
{
if (parameters == null) return string.Empty;
var val = parameters[0];
return Value.Replace(“@me“, val);
}
}
public class DateFormat : Parameter
{
public override string GetValue(params string[] parameters)
{
if (parameters == null) return string.Empty;
DateTime t;
if (DateTime.TryParse(parameters[0], out t))
{
return t.ToString(Value);
}
return parameters[0];
}
}
呵呵,GetValue貌似不是很漂亮,但确实解决了传值不定的情况。那我们如何实例化ParameterCollection的呢?(其实就是看怎么实例化这些Parameter的)
/// Parameter集合
/// </summary>
public class ParameterCollection : IEnumerable<Parameter>
{
private static readonly Regex FindPattern = new Regex(@”(?<name>\w+)=(?<value>(“”([^””]+)””)|(‘[^’]+’)|([^\s\}]+))“, RegexOptions.Compiled);
private readonly IDictionary<string, Parameter> _dict;
public ParameterCollection(string parameterString)
{
//两个return都会造成_dict为null,枚举此类的时候会抛异常,所以把dict实现实例化了
_dict = new Dictionary<string, Parameter>();
if (parameterString == string.Empty) return;
var matches = FindPattern.Matches(parameterString);
if (matches.Count == 0) return;
//开始初始化所有Parameter
foreach (Match m in matches)
{
var name = m.Groups[“name“].Value;
var value = m.Groups[“value“].Value;
_dict.AddValue(name, ParameterFactory.Create(name, value));
}
}
public Parameter this[string key]
{
get { return _dict[key]; }
}
public IEnumerator<Parameter> GetEnumerator()
{
foreach (var item in _dict)
{
yield return item.Value;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}

{
if (dict.ContainsKey(key))
{
dict[key] = value;
}
else
{
dict.Add(key, value);
}
}
代码最会说话,我就不废话了,可以看到这是一个还没完工的Collection,而创建Parameter部分不在这,在Factory 哈哈。
{
private static readonly Regex FuncPattern = new Regex(@”(?<func>\w+)\((?<parameter>[^)(]+?)\)“, RegexOptions.Compiled);
/// <summary>
/// 获取一个Parameter
/// </summary>
/// <param name=”name”></param>
/// <param name=”value”></param>
/// <returns></returns>
public static Parameter Create(string name, string value)
{
Parameter parameter;
if (IsSpecialParameter(name))
{
parameter = GetParameterByName(name);
}
else if (FuncPattern.IsMatch(value))
{
parameter = GetParameterByName(name);
}
else
{
parameter = new Parameter(name, value);
}
return parameter;
}
/// <summary>
/// 是否为特殊名称的Parameter
/// </summary>
/// <param name=”name”></param>
/// <returns></returns>
private static bool IsSpecialParameter(string name)
{
return false;
}
/// <summary>
/// 根据参数名获取Parameter(例如format=”e.g@me”)
/// </summary>
/// <param name=”name”></param>
/// <returns></returns>
private static Parameter GetParameterByName(string name)
{
//通过反射创建Parameter类
return null;
}
/// <summary>
/// 根据参数值获取Parameter(例如”Url(articleid)”)
/// </summary>
/// <param name=”value”></param>
/// <returns></returns>
private static Parameter GetParameterByValue(string value)
{
return null;
}
}
方法内部我没写如何实现,无外乎就是反射,所以大家理解思路即可。先判断是否有特殊的name,然后再判断是否有特殊的value,最后再是最普通的。
这样感觉就灵活的很多,而且如果用户想自定义一些function扩展,自需要在这几的程序集的特定名字空间下实现Parameter的继承,系统会自动find到这个特殊name或value。 不过实际应用中貌似这种需求不是很多,一般系统提供的足够用了。
写了好几个小时,才刚写好Parameter,后面再说Field的吧,Field还是比较复杂的。