Вызов кода как до, так и после метода WebControl.Render - PullRequest
2 голосов
/ 16 апреля 2010

У меня есть набор пользовательских серверных элементов управления 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
      }

  }

Если бы я извлекал все свои пользовательские элементы управления из одного и того же базового класса, я мог бы использовать шаблонный метод для обеспечения поведения до / после, но у меня есть несколько базовых классов, и я бы не хотел в конце концов получится действительно запутанная иерархия классов.

Такое ощущение, что я должен быть в состоянии разработать что-то более элегантное (т.е. придерживаться DRY и OCP), используя функциональные аспекты C #, но я рисую пробел.

1 Ответ

1 голос
/ 16 апреля 2010

У вас есть необязательное поведение, которое вы хотите добавить к некоторым объектам, а не к другим. Это означает, что в вашей задаче есть шаблон Proxy . Создайте элемент управления, который является контейнером для других элементов управления и выполняет необходимые действия до и после отрисовки любого из его дочерних элементов.

Вы правы, что не хотите наследовать, чтобы специализироваться. Наследовать для создания абстракций и вариаций. Делегат по специализации.

EDIT

/// <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 -->");
  }
}
...