Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Typenabhängige Ausführung von unterschiedlichen Klassen über Dictionary
MeisterPetz
myCSharp.de - Member



Dabei seit:
Beiträge: 2

Themenstarter:

Typenabhängige Ausführung von unterschiedlichen Klassen über Dictionary

beantworten | zitieren | melden

    class BuchBox : IBuchBox
    {
        public Dictionary<string, Buch> Buchmenge { get; private set; }
        public BuchBox(Dictionary<string, Buch> buchmenge)
        {
            this.Buchmenge = buchmenge;
        }
    }

    class ZeitschriftenBox
    {
        public Dictionary<string, Buch> Zeitschriftenmenge;
        public ZeitschriftenBox(Dictionary<string, Buch> zeitschriftenmenge)
        {
            this.Zeitschriftenmenge = zeitschriftenmenge;
        }
    }

    class MedienManager
    {
        IBuchBox buchstaender;
        IZeitschriftenBox zeitschriftenstaender;

        private Dictionary<string, object> verbinder;
		
		private Dictionary<string, Type> typenverbinder;

        public MedienManager(IZeitschriftenBox zeitschriftenstaender, IBuchBox buchstaender)
        {
            this.zeitschriftenstaender = zeitschriftenstaender;
            this.buchstaender = buchstaender;
            this.verbinder = new Dictionary<string, object>()
            {
                {"Buch", this.buchstaender },
                {"Zeitschrift", this.zeitschriftenstaender }
            };
			this.typenverbinder = new Dictionary<string, Type>()
			{
				{"Buch", typeof(IBuchBox)},
				{"Zeitschrift", typeof(IZeitschriftenBox)}
			};
        }

        public void SetzeInhalt(string art, string eigenschaft, string wert)
        {
			var medium = Convert.ChangeType(this.verbinder[art], this.typenverbinder[typ]);
			//trotzdem weiter vom Typ object
			medium.oeffnen();
			var seitenAnzahl = medium.GetType().GetProperty("SeitenAnzahl").GetValue(medium); 
			// medium wird als Typ erkannt und die jeweiligen Methoden/Properties sind nutzbar?
        }
    }

Hallo,
ich hoffe mir kann jemand weiterhelfen.
Ich habe oben die Definition einiger Klassen und der Interfaces weggelassen,
da sie sich denke mal aus den Kontex schließen lassen.

Hier die Frage:
Zeitschrift und Buch haben einige unterschiedliche Eigentschaften und
können nicht das selbe Interface nutzen(durch externes SDK nicht möglich).
Ich möchte natürlich nicht alle Funktionen von Buch(extern) in Buchbox
implementieren um sie über mit zu nutzen.

 Dictionary<string, Action<Delegate>> verbinder
Ziel ist dadurch einen Zugriffspunkt zu schaffen und den Zugriff auf das
SDK nicht überall im Code zu verteilen.


Sorry für das schlechte Beispiel ;-) Ich hoffe mir kann jemand weiterhelfen.
Gruß!
private Nachricht | Beiträge des Benutzers
mfe
myCSharp.de - Member



Dabei seit:
Beiträge: 177

beantworten | zitieren | melden

Leider sehe ich die Frage nicht eindeutig.

Ich hätte aber gemeint du könntest evtl. was mit dem Adapter-Pattern anfangen.

Mit dem Dictionary kannst du dahingehend auch schon einiges machen.

Eine möglicher Ansatz wäre z.B:

Dictionary<Typ, IAdapter> _AdapterDictionary
_AdapterDictionary.Add(typeof(BookAmazonType),AdapterAmazon);
_AdapterDictionary.Add(typeof(BookStadtBibliothekType),AdapterStadtBibliothek);

Für jedes Interface das gewrappt werden muss erstellst du einen Adapter. Z.b. AdapterAmazon,AdapterStadtBibliothek,AdapterC... die IAdapter implementieren.

Im _AdapterDictionary hinterlegst du für jeden Typ die passende Adapterinstanz. Zugriff könnte dann so aussehen.

_AdapterDictionary[CustomTyp.GetType()].GetBook("");
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von mfe am .
private Nachricht | Beiträge des Benutzers
Palin
myCSharp.de - Member



Dabei seit:
Beiträge: 1.090

beantworten | zitieren | melden

So genau habe ich jetzt auch nicht verstanden was du machen möchtest.
Für mich klingt es jetzt ein bisschen nach einen einfachen IoC-Container.

Tim Ross:Creating a Simple IoC Container
Sollte man mal gelesen haben:

Clean Code Developer
Entwurfsmuster
Anti-Pattern
private Nachricht | Beiträge des Benutzers
LaTino
myCSharp.de - Experte

Avatar #avatar-4122.png


Dabei seit:
Beiträge: 3.003
Herkunft: Thüringen

beantworten | zitieren | melden

a) verstehe ich nicht, worin sich IZeitschriftenbox und IBuchBox unterscheiden. Außer in den Namen jetzt. Das ist nach meinem Verständnis EINE Klasse.

b) du beziehst dich auf Klassen "Buch" und "Zeitschrift", die in einem externen SDK deklariert sind. Okay, gut, aber in deinem Codebeispiel kommt "Zeitschrift" gar nicht vor. Was sollen wir also mit der Information anfangen?

c) so, wie da Dictionaries verwendet werden, und auch der "SetzeInhalt"-Methode nach zu urteilen, besteht an irgendeiner Stelle ein grundlegendes Missverständnis, was objektorientieres Programmieren angeht.

Ich kann hier nur raten: wenn dein Problem ist, dass du zwei Klassen hast, die nicht miteinander verwandt sind, aber diese beiden Klassen gern generisch gemeinsam verwalten möchtest, dann:

- Schaffe ein gemeinsames Interface
- schaffe zwei Wrapperklassen, die dieses Interface implementieren, und jeweils Buch und Zeitschrift wrappen
- schaffe pro Wrapper vereinheitlichte Zugriffsmöglichkeiten auf Eigenschaften der gewrappten Objekte

(s.a. Facade-Pattern oder Proxy-Pattern oder Adapter-Pattern. Ich würde hier Facade bevorzugen.)

Dann kannst du zB eine allen gemeinsame Property "Seitenanzahl" einführen und direkt "SetzeInhalt" wegwerfen. (Und bitte, tu das. Reflection einzusetzen, um Architekturschwächen zu kompensieren, ist einfach nur bäh.)

LaTino
EDIT: @Palin: Kanone und Spatzen ;)
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von LaTino am .
"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)
private Nachricht | Beiträge des Benutzers
MeisterPetz
myCSharp.de - Member



Dabei seit:
Beiträge: 2

Themenstarter:

beantworten | zitieren | melden

Vielen Dank für die Antworten! Das Beispiel war wirklich schlecht gewählt und meine Problematik auch schlecht beschrieben, Entschuldigung dafür.
Ok hier die richtige Aufgabenstellung/Problemstellung:
Ich nutze die Baumer GAPI SDK um eine Ansteuerung für eine GeniCam Kamera zu bauen(also Bachelorarbeit). Die SDK hat einige Hauptklassen mit Methoden und Properties zum Beispiel:
System, Interface, Device.
Für jede dieser Klassen habe ich eine Wrapper-Klassen mit dem Inhalt:

Dictionary<string, System> systemRelation{get; private set;} // string =  Id
Diese werden Unity Container verwaltet (so vorgeschrieben).

Für jede gewrappte Klasse wird auch eine "Fassade"-Klasse erstellt:
Diese implementiert alle gebrauchte Funktionalität der originalen Klasse.


    public class GenTlSystem
    {
        private readonly ISystemWrapper systemWrapper;

        public GenTlSystem(ISystemWrapper systemWrapper, string id)
        {
            this.systemWrapper = systemWrapper;
            this.Id = id;
        }

        public string Id { get; private set; }

        public void Close()
        {
                this.systemWrapper.SystemRelation.FirstOrDefault(n =>n.Key.Equals(this.Id)).Value.Close();    
        }

        public void Open()
        {
                this.systemWrapper.SystemRelation.FirstOrDefault(n =>n.Key.Equals(this.Id)).Value.Open();        
        }
         public void SetValue(string node, object newValue)
         {
           this.systemWrapper.SystemRelation.FirstOrDefault(n =>n.Key.Equals(this.Id)).Value. RemoteNodeList[node].value = newValue;
          }

    }
Diese Lösung funktioniert schon so, aber fühlt sich nicht sehr elegant an da Funktionen wie Open und SetValue für jede wieder implementiert werden muss.
Ziel wäre einen WrapperContainer zu erstellen, der alle Wrapper verwaltet und mit nur einer Linq Funktion die jeweiligen Objekte typunabhängig aufruft und die gewünschte Funktion ausführt in Form von:

wrapperContainer.Open( "System", "SystemId" );
wrapperContainer.SetValue("System", "SystemId", "FileName", "C://usw") 
Für das setzen der Werte habe ich ein Strategiemuster was abhängig des Typs umwandelt.

Gibt es eine effizientere und elegantere Lösungen?
Schonmal danke für die Hilfe und ein schönes Wochenende!
Gruß!
private Nachricht | Beiträge des Benutzers