Ich möchte Metadaten zu meinem Objektgraphen für nicht-domänenbezogene Daten hinzufügen, die mit meinen Objekten verbunden werden, aber nicht unbedingt zum Problemset dieser Domäne gehören. Zum Beispiel muss ich Sortiereinstellungen für meine Objekte speichern, damit die Reihenfolge, in der sie im UI erscheinen, vom Benutzer konfigurierbar ist. Die Sortierindizes sollten serialisierbar sein, damit die Objekte sich an ihre Positionen erinnern. Das ist nur eines von ein paar anderen Metadaten, die ich für meine Objekte persistieren muss. Mein erster Gedanke ist, dies zu lösen, indem ich eine MetadataItem und eine MetadataItemCollection habe, wobei die Basisklasse Entity ein "Meta"-Eigenschaft vom Typ MetadataItemCollection haben wird. Zum Beispiel:
public class MetadataItem
{
public string Name;
public object Data;
}
public class MetadataItemCollection
{
/* Alle normalen Sammlungsvorgänge hier. */
// Implementierungsspezifische interessante ...
public object Get(string name);
public MetadataItem GetItem(string name);
// Stark typisierte Getter ...
public bool GetAsBool(string name);
public string GetAsString(string name);
// ... oder über Generics typisiert werden könnte ...
public T Get(string name);
}
public class Entity
{
public MetadataItemCollection Meta { get; }
}
Ein paar Bedenken, die mir einfallen, sind:
- Serialisierung - die Datenbank hat eine einzelne Tabelle mit EntityID | Name | Value, wobei Value eine Zeichenfolge ist und alle Typen in eine Zeichenfolge serialisiert werden?
- Zukunftssicherung - was passiert, wenn der Typ (unwahrscheinlich) oder der Name eines Metadatenelements geändert werden muss?
-
Refaktorisierbarkeit - sollten die Schlüssel aus einer statischen Liste über Enum oder einer Klasse mit statischen Zeichenfolgeneigenschaften stammen, oder sollten freiform Zeichenfolgen erlaubt sein:
var i = entity.Meta["SortIndex"];
vs.
public enum Metadaten { SortIndex };
var i = entity.Meta[Metadaten.SortIndex];
vs.
public static class Metadaten
{
public static string SortIndex = "SortIndex";
}
var i = entity.Meta[Metadaten.SortIndex];
- Noch etwas anderes?
Gedanken, Ideen, Fallstricke???
Danke für Ihre Zeit.
Lösung:
Dem Vorbild von @Mark folgend, und nachdem ich das von Mark verlinkte Udi-Video gesehen habe, habe ich zwei neue Schnittstellen erstellt: IUiPresentation und IUiPresentationDataPersistor. Es ist wichtig zu beachten, dass keines der Objekte in meinem Entity-Objektmodell Kenntnis von diesen Schnittstellen hat; die Schnittstellen befinden sich in einer separaten Assembly und werden niemals von meinem Entity-Objektmodell referenziert. Das Zauberwerk wird dann über IoC in den Präsentationsmodellen durchgeführt. Es könnte so etwas sein wie folgt:
public class PhoneViewModel
{
IUiPresentationDataPersistor _uiData
IUiPresentation _presenter;
// Lassen Sie IoC die Abhängigkeit über ctor-Injektion auflösen.
public PhoneViewModel(Phone phone, IUiPresentationDataPersistor uiData)
{
_uiData = uiData;
_presenter = uiData.Get(phone); // Führt eine einfache Suche nach der ID des Telefons durch.
}
public int SortIndex
{
get { return _presenter.SortIndex; }
set { _presenter.SortIndex = value; }
}
public void Save()
{
_uiData.Save();
}
}
Es ist etwas komplizierter, da das ViewModel INotifyPropertyChanged implementiert, um all die Vorteile zu nutzen, die es bietet, aber das sollte die allgemeine Idee vermitteln.