Ich erstelle eine Klassenbibliothek, die in einer Reihe von Situationen verwendet werden kann: ASP.NET, Konsolenanwendungen, andere Klassenbibliotheken und XAML-Ziele wie Silverlight oder WPF.
Zunächst habe ich beschlossen, Sammlungen als IList zu exponieren. Aber beim Schreiben von Samples mit XAML habe ich festgestellt, dass ich ObservableCollection verwenden muss, wenn ich die Bindung an diese Sammlungen erleichtern möchte.
Was sind meine Optionen?
Ich könnte die Bibliothek dazu bringen, ObservableCollection verfügbar zu machen und dies auf Benutzer anwenden, die nichts mit XAML zu tun haben. Ist das eine schlechte Sache?
Ich könnte meine Klasse generisch machen, damit der Aufrufer den gewünschten Sammlertyp angeben kann, solange er ICollection vielleicht mit dem Standard Collection
implementiertIch könnte eine Reihe von Klassen erstellen, die ObservableCollection verwenden und eine, die nicht Foo und ObservableFoo sagt.
Ich könnte INotifyCollectionChanged in meiner Klasse implementieren, aber das scheint albern, wenn ObservableCollection es für mich tut.
Offensichtlich versuche ich, den Code sauber und einfach zu halten, aber die Unterstützung der Datenbindung scheint wichtig.
Irgendwelche Vorschläge?
Bearbeiten: Es wurde versucht, ein tragbares Klassenbibliotheksprojekt mit beiden Alternativen zu erstellen.
In Klasse Foo habe ich
%Vor%In der Klasse ObservableFoo habe ich
%Vor%Der sehr einfache Komponententestcode ist
%Vor%Der einzige Nachteil ist, dass das Testprojekt bei der Verwendung von ReadOnlyObservableCollection diesen Kompilierfehler
erhalten hatDer Typ 'System.Collections.ObjectModel.ReadOnlyObservableCollection'1' ist definiert in einer Assembly, die nicht referenziert ist. Sie müssen ein hinzufügen Verweis auf Assembly 'System.Windows, Version = 2.0.5.0, Culture = neutral, PublicKeyToken = 7cec85d7bea7798e, Retargetable = Ja '
In diesem Fall würde die Verwendung von ReadOnlyObservableCollection die Benutzer zwingen, einen Verweis auf System.Windows hinzuzufügen, was ein Nachteil ist.
Bearbeiten: Ich habe eine Lösung gefunden, die ich in meinem Blog veröffentlicht habe - siehe Wie mache ich eine Bibliothek gleichzeitig portabel und datenbindungsfreundlich?
Nun, es kommt darauf an. Wenn Sie eine reine Modellbibliothek schreiben, ist es nicht sinnvoll, WPF-spezifische Schnittstellen verfügbar zu machen. Dies würde die Benutzer zwingen, sich mit WPF-Bibliotheken zu verbinden, auch wenn sie dies nicht tun müssen. Selbst wenn es nicht wäre, entlarvt es etwas, das die Benutzer nicht brauchen werden, was kein gutes Design ist. IMHO.
Wenn Ihre Bibliothek nicht auf die Modellverwendung beschränkt ist, würde ich sie in mehrere Teile aufteilen: Kern für alle Anwendungsszenarien, WPF-abhängigen Teil mit WPF-spezifischen Schnittstellen, vielleicht ASP-spezifischen Teil mit ASP-spezifischen Funktionen und so auf. Die Benutzer werden die Teile auswählen, die sie benötigen, und sie verwenden.
Bearbeiten: Wie in @ Juliens Kommentar angegeben, ist ObservableCollection<T>
jetzt Teil des Kerns. Daher werden die Benutzer nicht von den WPF-spezifischen Bibliotheken abhängig gemacht. Trotzdem bleibt die Idee gleich. Für die WPF-Nutzung müssen Sie häufig bestimmte Funktionen anbieten / bearbeiten ( ObservableCollection
, INotifyPropertyChanged
/ DependencyObject
, Abhängigkeitseigenschaften, Benachrichtigungen nur im UI-Thread usw.). Dies bedeutet, dass sie zu einem separaten, WPF-spezifischen Teil des Projekts gehören.
Sie können also die Bibliothek aus mehreren Teilen zusammensetzen: Library.Core.dll mit Funktionen für die generische / Modellentwicklung, Library.WPF.dll mit WPF-spezifischen Dingen und mit Library.Core.dll, vielleicht Library. Console.dll und Library.ASP.dll ebenso. Benutzer von WPF verwenden Library.Core.dll und Library.WPF.dll, Konsolenprogramme benötigen möglicherweise Library.Core.dll und Library.Console.dll und so weiter.
Ich denke, dass die Low-Level-Komponenten Ihrer Bibliothek Schnittstellen bieten sollten, die für diese Komponenten auf dieser Abstraktionsebene sinnvoll sind, ohne Rücksicht darauf, wie die verschiedenen Konsumenten Ihrer API sie für ihre eigenen Anwendungen anpassen müssen .
Wenn beispielsweise eine zusammengesetzte WPF-Anwendung Ihre Komponenten verwenden würde, wäre es völlig angemessen, dass diese Anwendungen Ihre Komponenten in ein Modell oder View-Modell einbetten, das die angebotenen IList<T>
(oder besser: IEnumerable<T>
) anpasst durch Ihre Komponenten in eine ObservableCollection<T>
geeignet für die Bindung an eine Ansicht.
Eine Konsolenanwendung benötigt möglicherweise keinen solchen Overhead und könnte gerne IEnumerable<T>
verwenden.
Seien Sie vorsichtig, auch wenn Sammlungen als IList<T>
angezeigt werden. Dadurch können Benutzer Ihrer Bibliothek beispielsweise Elemente hinzufügen und entfernen, die möglicherweise nicht im Sinne der Benutzeroberfläche sind.
Tags und Links wpf .net c# silverlight