Question

Media Browser a un modèle de fournisseur, cela est essentiellement une chaîne de classes qui s'appelle dans un ordre particulier pour chaque entité.

Ainsi, par exemple, nous avons:

        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());

L'ordre des fournisseurs dans la liste est importants les fournisseurs d'ordre supérieur ont priorité sur ceux d'ordre inférieur.

Récemment, je l'ai essayé de faire cette extensible partie. Ainsi, une DLL tierce partie peut définir ses propres fournisseurs qui s'injectés dans notre chaîne.

Le problème est qu'une fois que vous tenez compte de 3e parties de s'injectent dans la chaîne vous perdez une place centrale pour définir cet ordre.

Ma solution actuelle que je suis un peu mal à l'aise avec est de définir un attribut de priorité en option avec chaque fournisseur puis commande par la priorité.

Ainsi, par exemple, j'ai maintenant:

[ProviderPriority(20)]
class ImageByNameProvider{}

Cela permet 3ème parties de définir leur position dans la chaîne.

Une autre solutions que je pensais à propos étaient avant et après l'attribut Ex.

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

Mais, je ne sais pas si cela est plus facile ou plus difficile à programmer contre.

Y at-il d'autres solutions à ce problème? Quelle solution vous aller avec?

Peut-être, je devrais garder la liste des fournisseurs de base et ajouter le avant / après attribs pour les fournisseurs tiers ...

Était-ce utile?

La solution

Il semble qu'il y ait en fait quelques questions différentes qui devraient être abordés. Le problème fondamental tente de trouver un mécanisme qui permet à un objet arbitraire à insérer dans une liste existante à un moment donné au milieu de cette liste.

Vous ne décrit pas ce que l'interface IMetadataProvider ressemble vraiment, mais il devrait avoir un moyen pour identifier un fournisseur (meilleure option serait d'utiliser un Guid). L'avantage sur l'utilisation du nom de la classe est qu'il vous permet de renommer les classes au besoin pendant refactoring, etc. sans affecter les fournisseurs personnalisés (3ème partie) aussi longtemps que vous gardez le Guid même.

Au lieu d'utiliser une liste simple, vous devriez probablement obtenir votre propre liste:

class ProviderList : List<IMetadataProvider { }

qui expose une façon pour un fournisseur sur mesure (3ème partie) pour installer / désinstaller lui-même de cette liste. Ces mécanismes doivent être assez intelligents pour savoir comment insérer le nouveau fournisseur dans le milieu de la chaîne, mais aussi assez intelligent pour savoir comment gérer plusieurs fournisseurs personnalisés qui ont été insérées. De même, le processus de suppression doit être intelligent et faire face à des préoccupations similaires et également veiller à ce que quelqu'un ne cherche pas à supprimer l'un de vos fournisseurs « de base ».

Une bonne approche ici serait probablement de passer le Guid du fournisseur que vous souhaitez insérer après en tant que paramètre à la méthode d'installation (). La méthode remove () serait également prendre la Guid du fournisseur à supprimer.

Par exemple, dire insérer un nouveau fournisseur après MovieProviderFromXml. Puis une autre 3ème partie installe également un nouveau fournisseur après MovieProviderFromXml. Ce que le nouvel ordre de la chaîne devrait être? Le deuxième fournisseur insérer toujours immédiatement après MovieProviderFromXml ou faut-il commencer par là et sauter passé les fournisseurs personnalisés et insérer après le dernier fournisseur personnalisé installé (donc juste avant le prochain fournisseur « de base »?

associés à cette question est l'idée que vous avez besoin d'avoir un moyen de faire la distinction entre vos fournisseurs « de base » et un fournisseur personnalisé.

Enfin, vous devez vous assurer qu'il ya un moyen de gérer les défaillances de la chaîne, en particulier lorsqu'un fournisseur personnalisé est inséré dans le mauvais endroit.

Vous ne voulez toujours maintenir une base ( « maître ») la liste de votre chaîne par défaut. Lorsqu'un nouveau fournisseur est installé au milieu de cette chaîne, une nouvelle chaîne devrait être créé, mais vous ne voulez pas perdre la chaîne de base. Cela vous donne la possibilité de réinitialiser la chaîne à l'état par défaut.

Chaînage en fonction des priorités est problématique que vous avez alors de déterminer comment gérer les collisions prioritaires. En ce qui concerne un ensemble Avant / Après l'attribut, seriez-vous permettre à la fois sur le même fournisseur? Probablement pas, il serait plus logique de créer un ProviderChainAttribute qui possède une propriété enum ChainInsert, où ChainInsert définit avant et après les valeurs ENUM. Cela vous permet de forcer le fournisseur personnalisé pour prendre une décision quant à savoir si elle installe avant ou après que le fournisseur spécifié. Je continue à utiliser un Guid plutôt que le type.

Espérons que cela vous donne d'autres idées sur la façon d'aborder ce problème.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top