none
Dynamischer Klassen-Aufruf RRS feed

  • Frage

  • Wir haben ein Einstiegsprogramm, wo über eine gefilterte [User, Mandant] Datenbank ein   Datagrid  gefüllt wird. Jetzt kann der Anwender durch einen Doppelklick das Programm starten.

    Beim Aufruf wird noch ein Parameter mitgegeben, über den dann das Programm unterschiedlich reagiert. Es kommt vor, das ein Programm mehrfach im Menü steht und nur über unterschiedliche Parameter sich an den jeweiligen Benutzer anpasst.

     Heute haben wir es so gelöst:

    DataRow dr = ((DataRowView)bd_menu.SelectedItem).Row;
    string _pgm = dr.ItemArray[11].ToString().ToLower().Trim();
    string _parm = dr.ItemArray[12].ToString();
    if (_pgm=="sr_sdp")  
                    {
                        sr_sdp call_pgm = new sr_sdp();
                        call_pgm.ShowDialog(_parm);
                    } 
            else if (_pgm=="as_sdp")
                    {
                        as_sdp call_pgm = new as_sdp();
                        call_pgm.ShowDialog(_parm);
                    } 
    ...........

    Ist natürlich unnötige Schreibarbeit, da die  DataGrid  schon alle Informationen hat. Uns schwebt eine Lösung wie folgt vor:

    DataRow dr = ((DataRowView)bd_menu.SelectedItem).Row;
    string _pgm = dr.ItemArray[11].ToString().ToLower().Trim();
    string _parm = dr.ItemArray[12].ToString();
    if  (!string.IsNullOrWhiteSpace(_pgm))  
                    {
                        ExecuteDyn call_pgm = new ExecuteDyn(_pgm);
                        call_pgm.ShowDialog(_parm);
       }

    Hat jemand eine Idee, wie man dies mit ein paar Code-Zeilen erreichen kann, ohne für 100 Aufrufe gleich 500 Zeile tippen zu müssen.

    Gruß Edgar

    Donnerstag, 30. August 2012 12:44

Antworten

Alle Antworten

  • Ein schönes Beispiel für Softwarearchitektur. Es handelt sich im Grunde um das Strategy Pattern.

    D.h. deine Klassen sr_sdp, as_sdp brauchen eine Vererbungshierarchy entweder mittels Interface oder abstrakter Basisklasse. Dann reduziert sich der Code schon mal zu

    i_sdp call_pgm = null;
    
    if (_pgm=="sr_sdp")  
    {
       call_pgm = new sr_sdp();
    } 
    else if (_pgm=="as_sdp")
    {
       call_pgm = new as_sdp();
    }
    
    call_pgm.ShowDialog(_parm);   
         

    Und jetzt muss man nur noch die If's beseitigen. Auf Grund deiner Namenskonvention sollte das einfach per Reflektion gehen. D.h. suche dir über den Wert in _pgm die passende Klasse.

    Eine alternative ist ein IoC-Kontainer wie Unity, der das automatisch kann. Dann reduziert der Aufwand sich zu

    i_sdp call_pgm = unityContainer.Resolve<i_sdp>(_pgm);
    call_pgm.ShowDialog(_parm);   

    Es geht auch jeder andere IoC/DI-Mechanismus. Z.B. Managed Extensibility Framework (MEF).



    Donnerstag, 30. August 2012 15:00
  • Hallo Stefan,

    Danke für den schnellen Hinweis, genau so was suche ich.

    Ich wollte den namespace   Microsoft.Practices.Unity.dll im VS2010 installieren. Leider habe ich nur den Download für vs2008 gefunden und trotzdem versucht zu laden, ging leider nicht.

    Jetzt habe ich die Lösung und kann es nicht umsetzen, gib mir bitte noch einen Tipp.

    Gruß Edgar

    Donnerstag, 30. August 2012 16:39
  • Hi Edgar,

    benutze doch MEF (Post oben).

    Ist im Frameworke 4.0 mit drin.

    MFGBjörn

    Donnerstag, 30. August 2012 16:47
  • Gibts auf CodePlex: Enterprise Library. Bzw. Unity stand-alone: patterns & practices - Unity.

    Donnerstag, 30. August 2012 16:47
  • Hallo Edgar Wenisch,

    Ich gehe davon aus, dass die Antworten Dir weitergeholfen haben.
    Solltest Du noch "Rückfragen" dazu haben, so gib uns bitte Bescheid.

    Grüße,
    Robert


    Robert Breitenhofer, MICROSOFT   Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Donnerstag, 6. September 2012 15:03
    Moderator
  • Hallo Robert,

    es geht jetzt. Hat allerdings ein wenig länger gedauert, da mir das ganze Umfeld noch neu ist und Stefan einen Lösungsansatz aufgeführt hat, der noch zu komplettieren war.

    Allerdings habe ich jetzt eine Lösung ohne "Unity.dll" gefunden durch den Ansatz von Stefan.

    // ein Interface
    
        interface iExecuteClass
        {
            string ExecuteClass(String str);
        }
    
    //  in der gerufenen Klasse ein Verweis auf Interface
    
     public partial class sr_sdp : Window, iExecuteClass
    
    
    //  der dynamische Aufruf
    
    string _pgm = "sr_sdp";
    string _parm = "4711";
    string _done = "";
    
    var type = Type.GetType("NV_Projekt.Programme." + _pgm);
    var myObject = (iExecuteClass)Activator.CreateInstance(type);
    _done = myObject.ExecuteClass(_parm);
    

    Danke für Eure Hilfe

    Gruß Edgar

    Dienstag, 11. September 2012 12:31