W jaki sposób delegat może odpowiedzieć na wiele zdarzeń klasą ogólną i rozszerzalną?

Skonstruowałem technikę obsługi wielu podraportów w raporcie rdlc, ale ponieważ próbowałem uczynić go generycznym i powtarzalnym, musiałem wziąć model i nieco go ulepszyć dla każdego przypadku.

Na przykład, jeśli zdefiniuję abstrakcyjny interfejs, taki jak ten, po prostu wycinam i wklejam go z winform do winform w razie potrzeby:

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

Po pierwsze, chcę być w stanie wprowadzić to do każdego formularza, włączając obiekt ma-a. Chcę również opisać zachowania związane z obsługą wysyłania przez delegata i sprawić, aby metody obsługi były również „ogólne”.

Wymagania projektowe są następujące:

Utwórz obiekt, który może być zawarty w winformie, aby obsługiwać przetwarzanie wielu podraportówUtwórz instancję i skonfiguruj obiekt w winformieZbuduj tabelę wysyłki lub instrukcję switch / case w winformiePodaj wszystkie metody obsługi specyficznych wymagań przeglądarki raportów tej winformy

Celem jest stworzenie obiektu, który może być testowany osobno i wykonany jako odporny, a także nie trzeba wycinać i wklejać koła i wykonywać wielu ręcznych poprawek dla każdej nowej winformy.

Wydaje mi się, że ktoś znalazł lepszy projekt niż obecnie.

Utwórz obiekt, który może być zawarty w winformie, aby obsługiwać przetwarzanie wielu podraportów

Do tej pory mam delegata na zdarzeniu ładowania formularzy lokalnych:

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

które jest obsługiwane przez instrukcję switch w metodzie * LocalReport_SubreportProcessing *.

Treść metody zawiera instrukcję switch:

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;
            }
Na bok:

Moim zdaniem przełącznik jest w większości czytelny dla człowieka w porównaniu z alternatywą, którą rozważałem. Rozważałem użycie skrótu z nazwą raportu jako klucza i danych wywołania funkcji jako wartości. Jednak tak naprawdę nie wiedziałem, jak to zrobić i pomyślałem, że trudniej będzie komuś zrozumieć.

Następnie następuje wywołanie funkcji, która zmienia układ informacji przekazanych z wywołania funkcji w instrukcji switch:

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

Ta zmiana jest zdecydowanie jąkaniem kodu, ale jest pozornie niezbędna w stosunku do wzorca strategii, który próbuję wdrożyć:

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

        }

Oto konkretne wdrożenie strategii dla jednego ze sprawozdań:

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

        }
    }

W każdym razie moim pragnieniem jest, aby nie musieć wielokrotnie przekazywać tej samej logiki między raportami, ponieważ mam wiele raportów z wieloma podraportami.

Chciałbym, aby biblioteka korzystała z klasy do dynamicznego tworzenia części środkowych, w których występuje jąkanie, i chciałbym przekazać funkcję „anonimową”, która faktycznie implementuje szczegółowe połączenie podraportu z odpowiadającym mu źródłem danych.

W przypadku pojedynczego raportu z podraportami, a nawet kilku jednorazowych raportów, to, co robię, jest w porządku, ale jak można je uczynić mniej ręcznym, solidniejszym i bardziej testowalnym?

Moje środowisko to Visual Studio 2008 z celem .NET 3.5; wydaje się, że istnieje różnica w sposobie deklarowania klas abstrakcyjnych i ich kompilacji.

questionAnswers(1)

yourAnswerToTheQuestion