我有一组自定义ASP.NET服务器控件,其中大部分源自CompositeControl。我想通过将每个控件包装在特定的HTML / CSS标记中来实现对所有控件类型的“必需”字段的统一查找。例如:
<div class="requiredInputContainer">
...custom control markup...
</div>
我喜欢以这样的方式抽象这种行为,以避免在每个自定义控件,现在和将来都做这样丑陋的事情:
public class MyServerControl : TextBox, IRequirableField {
public IRequirableField.IsRequired {get;set;}
protected override void Render(HtmlTextWriter writer){
RequiredFieldHelper.RenderBeginTag(this, writer)
//render custom control markup
RequiredFieldHelper.RenderEndTag(this, writer)
}
}
public static class RequiredFieldHelper{
public static void RenderBeginTag(IRequirableField field, HtmlTextWriter writer){
//check field.IsRequired, render based on its values
}
public static void RenderEndTag(IRequirableField field, HtmlTextWriter writer){
//check field.IsRequired , render based on its values
}
}
如果我 从同一个基类派生所有自定义控件,我可以想象使用模板方法来强制执行前/后行为;但我有几个基类,我宁愿无论如何,最终还是没有真正复杂的类层次结构。
感觉我应该能够通过利用C#的功能方面来设计更优雅的东西(即坚持DRY和OCP),但我正在画一个空白。
答案 0 :(得分:1)
您有一个可选行为要添加到某些对象而不是其他对象。这意味着您的问题中存在Proxy模式。创建一个控件,它是其他控件的容器,并在渲染任何子控件之前和之后完成所需的操作。
你不想继承专业化是对的。继承以创建抽象和变体。委托专业化。
修改强>
/// <summary>
/// Create one of these panels for each required control
/// then place the required control into it
/// </summary>
public class ContainerForRequiredControls : Panel
{
protected override void Render(HtmlTextWriter writer)
{
writer.Write("<!-- header -->");
RenderChildren(writer);
writer.Write("<!-- footer -->");
}
}