Wie kann ein Delegat mit einer generischen und erweiterbaren Klasse auf mehrere Ereignisse reagieren?

Ich habe eine Technik entwickelt, um mehrere Unterberichte in einem rdlc-Bericht zu verarbeiten, aber da ich versucht habe, es generisch und wiederholbar zu machen, musste ich stattdessen das Modell nehmen und es für jeden Fall leicht anpassen.

Wenn ich zum Beispiel eine abstrakte Schnittstelle wie diese definiere, schneide ich sie einfach aus und füge sie nach Bedarf von winform in winform ein:

abstract class ISolutionStrategy
{
    public abstract void AlgorithmInterface(Int64 searchCriteria, SubreportProcessingEventArgs e);
}

Zunächst möchte ich in der Lage sein, dies in jede Form zu bringen, indem ich ein has-a-Objekt einbinde. Ich möchte auch das Verhalten der Abwicklung des Dispatchings durch den Delegaten zusammenfassen und die Abwicklungsmethoden ebenfalls "generisch" gestalten.

Die Designanforderungen sind also:

Erstellen Sie ein Objekt, das in eine Winform aufgenommen werden kann, um die Verarbeitung mehrerer Unterberichte zu verarbeitenInstanziieren und konfigurieren Sie das Objekt in der WinformErstellen Sie die Dispatch-Tabelle oder die Switch / Case-Anweisung in der WinformÜbergeben Sie alle Methoden, um die spezifischen Anforderungen des Berichts-Viewers dieser Winform zu erfüllen

Das Ziel ist es, ein Objekt zu erstellen, das eigenständig getestet und robust gemacht werden kann, und das Rad nicht auszuschneiden und einzufügen und für jede neue Winform eine Reihe manueller Anpassungen vorzunehmen.

Es scheint mir, dass jemand ein besseres Design gefunden hat als das, das ich derzeit habe.

Erstellen Sie ein Objekt, das in eine Winform aufgenommen werden kann, um die Verarbeitung mehrerer Unterberichte zu verarbeiten

Bisher habe ich einen Delegierten im Ladevorgang für lokale Formulare:

this.reportViewer1.LocalReport.SubreportProcessing += new SubreportProcessingEventHandler(LocalReport_SubreportProcessing);

Dies wird von einer switch-Anweisung in der * LocalReport_SubreportProcessing * -Methode behandelt.

Der Hauptteil der Methode enthält eine switch-Anweisung:

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;
            }
Beiseite:

Meiner Meinung nach ist der Schalter im Vergleich zu der von mir in Betracht gezogenen Alternative größtenteils von Menschen lesbar. Ich überlegte, einen Hash mit dem Berichtsnamen als Schlüssel und den Funktionsaufrufdaten als Wert zu verwenden. Ich wusste jedoch nicht genau, wie ich es machen sollte, und ich dachte, dass es für andere schwerer sein würde, es zu verstehen.

Danach wird eine Funktion aufgerufen, die die vom Funktionsaufruf in der switch-Anweisung übergebenen Informationen neu anordnet:

    private static void runSubAlternatePart(SubreportProcessingEventArgs e1, String  commonReportKey, GetAlternatePart myAP)
            {
                myAP.AlgorithmInterface(commonReportKey, e1);
            }

Diese Neuanordnung ist definitiv Code-Stottern, aber eine scheinbar notwendige Zwischenstufe zu dem Strategiemuster, das ich zu implementieren versuche:

     abstract class IStrategy
        {
            public abstract void AlgorithmInterface(String searchParam, SubreportProcessingEventArgs e);

        }

Hier ist eine konkrete Umsetzung der Strategie für einen der Berichte:

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]));
            }

        }
    }

In jedem Fall möchte ich nicht wiederholt dieselbe Logik zwischen Berichten verwenden müssen, da ich viele Berichte mit mehreren Unterberichten habe.

Ich möchte eine bibliotheksähnliche Methode, mit der mithilfe einer Klasse die mittleren Teile, in denen das Stottern auftritt, dynamisch erstellt werden, und ich möchte eine "anonyme" Funktion übergeben, die die detaillierte Verknüpfung des Unterberichts mit der entsprechenden Datenquelle ausführt.

Für einen einzelnen Bericht mit Unterberichten oder sogar ein paar Einzelberichten ist das, was ich mache, in Ordnung, aber wie kann es weniger manuell, robuster und testbarer gemacht werden?

Meine Umgebung ist Visual Studio 2008 mit einem Ziel von .NET 3.5; Es scheint einen Unterschied zu geben, wie abstrakte Klassen deklariert und wie sie kompiliert werden.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage