在WebControl.Render方法之前和之后调用代码

时间:2010-04-16 14:25:39

标签: asp.net abstraction custom-server-controls functional-programming

我有一组自定义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),但我正在画一个空白。

1 个答案:

答案 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 -->");
  }
}