title: How can a delegate respond to multiple events with a generic and extensible class?
body: <p>I have rigged up a technique to handle multiple subreports in an rdlc report, but as I have tried to make it generic and repeatable, I have instead had to take the model and tweak it slightly for each case.</p>
  
  <p>For example, if I define an abstract interface, like such, I just cut and paste it from winform to winform as needed:</p>
  
  <pre><code>abstract class ISolutionStrategy
  {
      public abstract void AlgorithmInterface(Int64 searchCriteria, SubreportProcessingEventArgs e);
  }
  </code></pre>
  
  <hr>
  
  <p>First, I want to be able to bring this into each form by including an has-a object. I also want to encapsulate the behaviors of handling the dispatching by the delegate, and make the handling methods "generic" as well.</p>
  
  <p>So, the design requirements  are:</p>
  
  <ul>
  <li>Create an object that can be included in a winform to handle multiple subreport processing</li>
  <li>Instantiate and configure the object in the winform</li>
  <li>Build the dispatch table or switch/case statement in the winform</li>
  <li>Pass in all the methods to handle the specific requirments of that winform's report viewer</li>
  </ul>
  
  <p>The GOAL is to make an object that can be tested standalone and made robust, and also to not have to cut and paste the wheel and do a bunch of manual tweaking for each new winform.</p>
  
  <p>It seems to me that someone has found a better design out there than the one I currently have.</p>
  
  <p>Create an object that can be included in a winform to handle multiple subreport processing</p>
  
  <p>So far, I have a delegate in the local forms load event:</p>
  
  <pre><code>this.reportViewer1.LocalReport.SubreportProcessing += new SubreportProcessingEventHandler(LocalReport_SubreportProcessing);
  </code></pre>
  
  <p>which is handled by a switch statement in the *LocalReport_SubreportProcessing* method.</p>
  
  <p>The body of the method contains a switch statement:</p>
  
  <pre><code>void LocalReport_SubreportProcessing(object sender, SubreportProcessingEventArgs e)
  
          {
              String commonSubreportKey = _commonSubreportKey;
  
              switch (e.ReportPath)
              {
                  case "rptSubAlternateParts":
                      runSubAlternatePart(e, commonSubreportKey, new GetAlternateParts());
                      break;
                  case "rptSubGetAssemblies":
                      runSubFailurePart(e, commonSubreportKey, new GetAssemblies());
                      break;
                  case "rptSubGetAssemblies":
                      runSubGetGetEndItemLRMFailureInfo(e, commonSubreportKey, new GetEndItemLRMFailureInfo());
                      break;
                  case "rptSubGetAssemblies":
                      runSubGetSubAssemblies(e, commonSubreportKey, new GetSubAssemblies());
                      break;
                  default:
                      break;
              }
  </code></pre>
  
  <blockquote>
    Aside:
    
    <p><em>In my opinion, the switch is mostly human readable compared to the
    alternative I considered. I considered using a hash with the report
    name as the key and the function call data as the value. However, I
    did not really know how to do it and I thought it would be harder for
    someone else to understand.</em></p>
  </blockquote>
  
  <hr>
  
  <p>After that, a call is made to a function that rearranges the information passed from the function call in the switch statement:</p>
  
  <pre><code>    private static void runSubAlternatePart(SubreportProcessingEventArgs e1, String  commonReportKey, GetAlternatePart myAP)
              {
                  myAP.AlgorithmInterface(commonReportKey, e1);
              }
  </code></pre>
  
  <p>This rearrangement is definitely code stuttering, but is a seemingly necessary intermediate to the Strategy pattern I am attempting to implement:</p>
  
  <pre><code>     abstract class IStrategy
          {
              public abstract void AlgorithmInterface(String searchParam, SubreportProcessingEventArgs e);
  
          }
  </code></pre>
  
  <p>Here is a concrete implementation of the Strategy for one of the reports:</p>
  
  <pre><code>class GetAlternatePart : IStrategy
  {
  private BLL.AlternatePartBLL ds = new BLL.AlternatePartBLL();
  
  
  public override void AlgorithmInterface(String searchParam, SubreportProcessingEventArgs e)
                {
  
                      e.DataSources.Clear();
                      DataTable myDataTable = ds.GetAlternativePart(searchParam);
                      DataSet myDataSet = new DataSet();
                      myDataSet.Tables.Add(myDataTable);
                  e.DataSources.Add(new ReportDataSource("BLL_AlternatePartBLL", myDataSet.Tables[0]));
              }
  
          }
      }
  </code></pre>
  
  <p>In any case, my desire is to not have to hand wire the same logic repeatedly between reports, as I have many reports with multiple subreports.</p>
  
  <p>I would like a library quality way of using a class to dynamically create the middle parts where the stuttering occurs, and I would like to pass in an "anonymous" funciton which actually implements the detailed connecting of the subreport to its corresponding data source.</p>
  
  <p>For a single report with subreports, or even a few one-off reports, what I am doing is ok, but how can it be made less manual, more robust and more testable?</p>
  
  <p>My environment is Visual Studio 2008 with a target of .NET 3.5; there seems to be a difference in how abstract classes are declared and how they are compiled.</p>