Danke für die Anregungen bisher.
Das mit der Facade ist mein aktueller Ansatz. Das ist auch so umgesetzt. Allerdings bin ich "genervt" von dem Injecten in jeder Klasse und wollte davon weg. Denn eigentlich greifen ja wirklich alle Klassen auf den selber Manager zu der vom Hauptprogramm bereit gestellt wird.
Im Moment mit der Facade klappt alles.
Ich wollte eben nur wissen ob es ein schlechter Ansatz ist auf diese Static Getter umzusatteln.
Das wäre eine Idee aber dann "verbaue" ich mir das Vererben. Ich kann dann ja von keiner anderen Klasse mehr erben, falls dies mal notwendig sein sollte.
Ausserdem muss ich den Manager ja trotzdem mit übergeben:
public abstract class MyBaseClass
{
public MyBaseClass(IDrawManager drawManager)
{
DrawManager = drawManager;
}
protected IDrawManager DrawManager { get; }
}
public class MyOtherClass : MyBaseClass
{
public MyOtherClass(IDrawManager drawManager) : base(drawManager)
{
public void DrawSomeThing()
{
DrawManager.DrawLine();
}
}
Diese Übergabe die im Construktor von MyOtherClass geschieht, die wollte ich eigentlich los werden.
Hallo,
meine Situation ist folgende:
Ich schreibe ein kleines Plugin für ein Programm. Die Spezifikation sieht vor das meine Plugin-dll eine Klasse enthalten muss die von der abstrakten Klasse "CustomPlugin" ableitet.
CustomPlugin wird dabei von dem Hauptprogramm bereit gestellt.
Das Hauptprogramm sucht in der dll nach der Klasse und lädt diese. Es gibt diverse Funktionen funktionen die die abstrakte Klasse bereit stellt und die ich dann überschreiben kann oder implementieren muss.
Weiterhin stellt das Hauptprogramm über die abstrakte Klasse Eigenschaften bereit. Diese Eigenschaften verweisen auf sogenannte "Manager". Mit der Verwendung der Manager z.B. DrawManager kann mein plugin das Hauptprogramm veranlassen etwas in sein Fenster zu zeichnen.
Soweit so gut.
Jetzt besteht mein Plugin aber nicht nur aus einer Klasse in einer Datei sondern aus mehreren.
Jetzt bin ich jedesmal dabei in jeder Klasse per Dependency Injection im Konstruktor diesen Manager und andere zu übergeben. Das ganze ist natürlich sehr nervig.
Meine Frage:
Kann ich nicht einfach eine statische Eigenschaft des Managers in meiner Hauptklasse erstellen und alle anderen Klassen greifen dann einfach darauf zu? Ist das schlechter Programmierstiel?
Rahmenbedingung sind auch das dieses statische Plugin nur einen Getter hat und nicht verändert werden kann.
Die Manager verändern sich durch das Hauptprogramm auch nicht, sie bleiben die ganze Zeit die selben nach dem initialisieren.
In Hinsicht auf TestBarkeit könnte ich meinen Klassen zusätzlich noch öffentliche Eigenschaften spendieren um den Manager der einzelnen Klassen expliziet zu setzen, so das diese Klasse nicht auf die statische Eigenschaft der Hauptklasse zurück greift.
GoodPractice/BadPractice? Gibt es andere Vorschläge?
Kurzes Beispiel wie ich es mir vorstellen anstatt in "MyOtherClass" im Constructor alle Manager zu übergeben.
public class MyPlugin : CustomPlugin
{
public static IDrawManager StaticDrawManager { get; private set; }
//wird vom Hauptprogramm durch CustomPlugin bereitgestellt
protected IDrawManager DrawManager { get; }
public override void Initialize()
{
//Methode wird vom Hauptprogram gerufen, initialisiere etwas
StaticDrawManager = DrawManager;
}
}
public class MyOtherClass
{
public MyOtherClass()
{
//beim initialisieren hole statischen Manager
DrawManager = MyPlugin.StaticDrawManager;
}
//kann aber für UnitTests oder andere Dinge von aussen überschrieben, "umgebogen" werden
public IDrawManager DrawManager { get; set; }
public void DrawSomeThing()
{
DrawManager.DrawLine();
}
}
Danke Bhaal.
Auf diese Bibliothek bezog ich mich auch als ich meinte ich habe das schon einmal gesehen.
Ich wusste aber nicht genau wie es umzusetzen ist.
Das Schlüsselwort zum Erfolg heisst hier also DependencyProperty? Das wollte ich nur wissen wonach ich in dem Quelltext suchen muss. Dann schaue ich mir den Quelltext einmal genauer an.
Es geht nicht um das "Bilderding". Das war nur ein Beispiel.
Es geht mir expliziet um die oben genannte Frage. Ich würde das gerne auch auf andere MarkupExtensions anwenden die andere Funktonalität besitzen.
Hi,
ich habe für diverse Zwecke eine eigene MarkupExtension erstellt und verwende diese im XAML Code.
Das funktioniert sehr gut. Ich habe z.B. eine MarkupExtension um Bilder nachzuladen und auf Buttons zu legen oder auch zur Lokalisation.
Allerdings steckt in all diesen MarkupExtensions immer eine winzige Funktionalität die sich auf das aktuelle Projekt bezieht. Somit lässt sich das ganze nicht in eine Bibliothek auslagern und universell nutzen.
Ich habe aber schon oft bei anderen Bibliotheken/Projekten gesehen das die MarkupExtension bevor sie benutzt wird im XAML Code configuriert wird.
Zum Beispiel so:
<window
x:Class="Klasse"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:local"
xmlns:images="clr-namespace:local.Images"
MinWidth="300" MinHeight="300"
images:ImageFolder="resourcen\images"
mc:Ignorable="d">
<Grid>
<ToolBarControl>
<BarButtonItem Content="test"
Glyph="{images:Image cmdSave, Size=Size16}"
LargeGlyph="{images:Image cmdSave}"/>
</ToolbarControl>
</Grid>
Wie man sieht wird bei dem BarButton das Glyph über die Image MarkupExtension gesetzt.
Und weiter oben (das ist was ich erreichen möchte) wird das ganze konfiguriert und gesagt wo die Bilder liegt:
images:ImageFolder="resourcen\images"
Wie wird sowas umgesetzt?
Wie gesagt bei anderen Projekten habe ich das schon gesehen das es möglich ist. Aber ich weiss nicht wie man es umsetzen kann.
Viele Grüße
Hi,
also ich hatte das Buch einmal auf deutsch gelesen:
C# 6 mit Visual Studio 2015: Das umfassende Handbuch: Spracheinführung, Objektorientierung, Programmiertechniken
Es ist meiner Meinung nach sehr gut. Fängt aber auch komplett von vorne an und geht dann aber auch noch über das reine c# hinaus indem es auch Dinge wie WPF behandelt.
Es gibt noch ein ähnlich Buch des Verlages:
Professionell entwickeln mit C# 6 und Visual Studio 2015: Das Praxisbuch. Alle Phasen in der Praxis: vom Entwurf bis zum Deployment.
Dies wird wohl dem Titel nach nicht ganz so auf C# Grundlagen eingehen.
Du kannst dir auch kostenlosden Vorgänger angucken und lesen:
http://openbook.rheinwerk-verlag.de/visual_csharp_2012/
Zu dem anderen Buch kann ich nichts beitragen.
Hi,
ich habe mich mal daran gemacht und die ersten Schritte unternommen.
Ich habe noch eine Frage, eventuell hast du einen einen Tipp.
Ich wollte in meinem Programm eine Art Fenster "Fehlerliste" erstellen. Ähndlich der Fehlerliste im Visual Studio.
Dort sollen immer alle Fehler aller Objekt sofort aufgesammelt und angezeigt werden.
Jetzt stellt sich mir die Frage, wenn ich z.B. IValidatableObject ode etwas ähnliches eigenes Implementiere, wie bekommt die GUI (WPF) mit das sich der validierte Zustand eventuell geändert hat.
Sollte ich an der Stelle selber ein event einführen, welches darüber benachrichtigt?
Wie macht das IDataErrorInfo? Wann ruft dieses die Fehlermeldungen wieder ab und aktualisiert sich. Ist das an INotifyPropertyChanged gekoppelt?
Hm, ok.
Dann werde ich diesen Weg einschlagen und versuchen umzusetzen.
Ich habe noch eine Frage zu deinem Beispiel.
Leitet IValidatableEntity von IValidatable ab.
Was ist der Unterschied zwischen IValidatable und IValidatableObject. Das habe ich auch noch gefunden.
Wo kommt die IsValid Methode her? Auch aus einem Standard-Interface oder wurde es von dir "eingeführt"?
Danke und viele Grüße
Ich denke das mit den DataAnnotations ist ein sehr guter Hinweis.
Das hatte ich so nicht auf dem Schirm.
Ich habe dazu auch ein passendes Video gefunden, das eigentlich das abfackelt was ich vorhabe.
Danke für den Tip.
Hier das Video:
C# DataAnnotations explained
Allerdings stört mich noch eine Sache daran. Jemand der die Core komponente verwendet muss selber von Hand die Überprüfung durchführen. Sprich es ist trotzdem möglich einen Namen der nicht mit "A" beginnt zu vergeben oder? Sprich man muss den Namen vergeben und anschließend immer prüfen ob dies mgl. ist oder?
Wie bekommt man eigentlich mit, welche Merkmale durch DataAnnotations eingeschränkt wurden, wenn man die Quelldaten nicht hat?