/// <summary>
/// Label基類
/// </summary>
public class Label
{
/// <summary>
/// ID,一般用於緩存的Key
/// </summary>
public string ID { get; set; }
/// <summary>
/// 原始的HTML代碼
/// </summary>
public string Html { get; set; }
/// <summary>
/// 標籤的參數
/// </summary>
public IDictionary<string,Parameter> Parameters { get; set; }
/// <summary>
/// 標籤的字段
/// </summary>
public IDictionary<string, Field> Fields { get; set; }
/// <summary>
/// 緩存
/// </summary>
public Cache Cache { get; set; }
/// <summary>
/// 獲取需要呈現的HTML
/// </summary>
/// <returns></returns>
public virtual string GetRenderHtml()
{
return string.Empty;
}
}
public class LabelFactory
{
/// <summary>
/// 匹配Label的正則
/// </summary>
private static readonly Regex LabelRegex = new Regex(@"{((?<a>\w+):(?<c>\w+))(?<p>[^}]*)((/})|(}(?<t>(?>(?<o>{\1[^}]*})|(?<-o>{/\1})|(?:(?!{/?\1)[\s\S]))*)(?(o)(?!)){/\1}))");
/// <summary>
/// 根據模版獲取其包含的所有Label
/// </summary>
/// <param name="template">模版</param>
/// <param name="preInit">Label初始化前需要的工作</param>
/// <returns></returns>
public static IList<Label> Find(string template, Action<Label> preInit)
{
var ms = LabelRegex.Matches(template);
if (ms.Count == 0) return null;
var list = new List<Label>();
foreach (Match m in ms)
{
var label = Create(m.Groups[0].Value, m.Groups["a"].Value, m.Groups["c"].Value, m.Groups["p"].Value, m.Groups["t"].Value);
//訂閱事件
if (preInit != null)
{
label.PreInit += preInit;
}
//查找Label的子Label,如果存在則會替換Label的TemplateString
var labels = Find(label.TemplateString);
if (labels != null)
{
label.TemplateString = label.TemplateString.Replace(labels[0].TemplateString, string.Empty);
}
//label.Init();
list.Add(label);
if (labels != null)
list.AddRange(labels);
}
return list;
}
/// <summary>
/// 重載上面的Find,一般情況下使用該方法,除非需要特殊處理某些標籤
/// </summary>
/// <param name="template"></param>
/// <returns></returns>
public static IList<Label> Find(string template)
{
return Find(template, null);
}
/// <summary>
/// 反射創建一個Label
/// </summary>
/// <param name="template">標籤的原始HTML,用於替換使用</param>
/// <param name="a">程序集名稱</param>
/// <param name="c">標籤類名稱</param>
/// <param name="p">標籤參數</param>
/// <param name="t">標籤的模版</param>
/// <returns></returns>
private static Label Create(string template, string a, string c, string p, string t)
{
var assembly = Assembly.Load(a);
var label = assembly.CreateInstance(c, true) as Label;
label.Html = template;
label.TemplateString = t;
label.ParameterString = p;
return label;
}
}
細心的朋友會發現Label又增加了些新內容,是的,這是在設計過程中的填充和修改。沒有人一開始就考慮的十分周全,這是一個正常的設計過程。看看Label的改動,增加了幾個屬性,一個preinit事件,和一個初始化方法init給定一段html代碼,裏面會包含若干個label,所以find會返回一個list,另外我們還需要一個Create方法類反射每一個label。
爲什麼設計了一個事件?
因爲Include標籤是需要傳參給裏面的label的,所以在label初始化之前可能會改動label的parameterString和templateString:) 希望您能理解。
/// <summary>
/// 原始的HTML代碼
/// </summary>
public string Html { get; set; }
/// <summary>
/// Label的Parameter字符串
/// </summary>
public string ParameterString { get; set; }
/// <summary>
/// Label的模版
/// </summary>
public string TemplateString { get; set; }
/// <summary>
/// 初始化之前的事件
/// </summary>
public event Action<Label> PreInit;
/// <summary>
/// 初始化Label
/// </summary>
public virtual void Init()
{
if (PreInit != null)
{
PreInit(this);
}
//初始化所有參數
Parameters = new ParameterCollection(ParameterString);
//初始化所有字段
Fields = new FieldCollection(TemplateString);
}
好了,寫了太久了,大家和我都消化消化,休息下:)後面繼續講Parameters和Fields的設計。