Frage

Medien-Browser hat ein Provider-Modell, das im Grunde eine Kette von Klassen, die in einer bestimmten Reihenfolge für jede Einheit aufgerufen.

So zum Beispiel haben wir:

        providers = new List<IMetadataProvider>();
        providers.Add(new ImageFromMediaLocationProvider());
        providers.Add(new ImageByNameProvider());
        providers.Add(new MovieProviderFromXml());
        providers.Add(new MovieDbProvider());
        providers.Add(new TVProviderFromXmlFiles());
        providers.Add(new TvDbProvider());
        providers.Add(new VirtualFolderProvider());
        providers.Add(new FrameGrabProvider());
        providers.Add(new MediaInfoProvider());

Die Reihenfolge der Anbieter in der Liste signifikante höhere Ordnung Anbieter haben Vorrang vor niedrigerer Ordnung.

Vor kurzem habe ich versucht, diesen Teil erweiterbar zu machen. So ein Dritter DLL kann seine eigenen Provider definieren, die in unserer Kette injiziert wird erhalten.

Das Problem ist, dass, wenn Sie für dritte Parteien lassen sich in der Kette injizieren Sie einen zentralen Platz zu verlieren, diesen Auftrag zu definieren.

Meine aktuelle Lösung, die ich ein wenig unangenehm bin mit ist ein optionales Prioritätsattribut mit jedem Provider zu definieren und dann Reihenfolge der Priorität.

So zum Beispiel habe ich jetzt:

[ProviderPriority(20)]
class ImageByNameProvider{}

Dies ermöglicht dritte Parteien ihre Position in der Kette zu definieren.

Einen anderen Lösungen, die ich daran gedacht waren vor und nach dem Attribut Eg.

[Before(typeof(ImageByNameProvider))]
class ImageFromMediaLocationProvider {} 

Aber, ich bin nicht sicher, ob dies leichter oder schwerer zu programmieren gegen.

Gibt es andere Lösungen für dieses Problem? Welche Lösung würden Sie gehen mit?

Vielleicht sollte ich einfach die Liste für die Kernanbieter und fügen Sie den Vorher / Nachher attribs für Drittanbieter ...

War es hilfreich?

Lösung

Es scheint, als ob es tatsächlich ein paar verschiedenen Themen hier ist, die angegangen werden soll. Das grundlegende Problem versucht, mit einem Mechanismus zu entwickeln, die ein beliebige Objekt erlaubt irgendwann zu einer bestehenden Liste eingefügt wird in in der Mitte dieser Liste.

Sie beschreiben nicht, was die IMetadataProvider Schnittstelle tatsächlich aussieht, aber es sollte eine gewisse Art und Weise hat eindeutig einen Anbieter zu identifizieren (beste Möglichkeit wäre, eine Guid verwenden). Der Vorteil gegenüber der Klassennamen ist, dass es Ihnen die Klassen umbenennen kann wie bei Refactoring benötigten usw. ohne individuelle (3rd party) Anbieter zu beeinflussen, solange Sie die Guid das gleiche bleiben.

Anstatt eine einfache Liste verwenden, sollten Sie wahrscheinlich Ihre eigene Liste ableiten:

class ProviderList : List<IMetadataProvider { }

, die für eine benutzerdefinierte (3rd Party) Anbieter eine Art und Weise macht sich die Installation / Deinstallation von dieser Liste. Diese Mechanismen müssen intelligent genug, um zu wissen, wie die neuen Anbieter einfügen in die Mitte der Kette, sondern auch intelligent genug, um zu wissen, wie mehrere benutzerdefinierten Provider zu handhaben, die eingeführt wurden. Ebenso muss der Entfernungsprozess als auch klug sein, mit ähnlichen Anliegen zu befassen und auch dafür sorgen, dass jemand nicht eine Ihrer „Kern“ Anbieter zu entbindet versuchen.

Ein guter Ansatz wäre hier wahrscheinlich die Guid des Anbieters Sie nach auf den () -Methode Installieren Sie als Parameter eingefügt werden sollen passieren. Die Remove () -Methode würde ebenfalls die Guid des Anbieters nehmen entfernt werden.

Zum Beispiel, sagen, dass ich einen neuen Provider nach MovieProviderFromXml einfügen. Dann wieder eine dritte Partei installiert auch einen neuen Provider nach MovieProviderFromXml. Was soll die neue Kette Ordnung sein? Hat der zweite Anbieter immer unmittelbar nach MovieProviderFromXml einfügen oder dort startet und dann überspringen Vergangenheit alle benutzerdefinierten Anbieter und einfügen nach dem letzten benutzerdefinierten Anbieter installiert ist (so kurz vor dem nächsten „Kern“ Provider?

auf diese Frage mit Bezug ist die Idee, die Sie brauchen eine Möglichkeit zu haben, zwischen dem „Kern“ Provider und einem benutzerdefinierten Anbieter zu unterscheiden.

Schließlich müssen Sie sicherstellen, dass es ein Weg gibt Fehler in der Kette zu handhaben, vor allem, wenn ein benutzerdefinierter Provider in der falschen Stelle eingefügt wird.

Sie wollen immer eine Basis ( „Master“) Liste der Standardkette aufrechtzuerhalten. Wenn ein neuer Anbieter in der Mitte dieser Kette installiert ist, sollte eine neue Kette erstellt werden, aber Sie wollen nicht auf die Basiskette zu verlieren. Dies gibt Ihnen die Möglichkeit, die Kette wieder in den Auslieferungszustand zurückgesetzt werden.

Basis Chaining auf Priorität ist problematisch, dass man dann bestimmen müssen, wie Priorität Kollisionen zu behandeln. Soweit ein Vorher / Nachher-Attribut gesetzt, Sie erlauben würden, beide auf dem gleichen Anbieter? Wahrscheinlich nicht, so könnte es mehr Sinn machen, eine ProviderChainAttribute zu erstellen, die eine ChainInsert Enum Eigenschaft hat, wo ChainInsert Vor und nach als ENUM-Werten definiert. So können Sie den benutzerdefinierten Anbieter zwingen, eine Entscheidung zu treffen, ob es installiert, bevor oder nach dem angegebenen Anbieter. Ich würde immer noch eine Guid verwenden, anstatt der Typ.

Hoffentlich gibt Ihnen einige andere Ideen, wie dieses Problem zu nähern.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top