Domanda

Browser media ha un modello di provider, questo è fondamentalmente una catena di classi che vengono chiamati in un ordine particolare per ogni entità.

Così, per esempio abbiamo:

        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'ordine dei fornitori della lista è significativi i fornitori di ordine superiore hanno la precedenza su quelle di ordine inferiore.

Recentemente, ho cercato di rendere questa porzione estensibile. Quindi una terza parte può DLL di definire i propri fornitori che andranno iniettati nella nostra catena.

Il problema è che una volta che si consente di 3 parti per iniettare se stessi nella catena si perde un posto centrale per definire questo ordine.

La mia soluzione attuale che sono un po 'a disagio con è quello di definire un attributo di priorità optional con ogni fornitore e poi ordinare dalla priorità.

Così, per esempio ora ho:

[ProviderPriority(20)]
class ImageByNameProvider{}

In questo modo 3 parti di definire la loro posizione nella catena.

Un altro soluzioni ho pensato erano prima e dopo l'attributo Eg.

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

Ma, io non sono sicuro se questo è più facile o più difficile da programmare contro.

Ci sono altre soluzioni a questo problema? Quale soluzione si va con?

Forse, dovrei solo continuare la lista per i fornitori di base e aggiungere la Prima / Dopo attribs per i fornitori di terze parti ...

È stato utile?

Soluzione

Sembra che in realtà vi sono alcuni problemi di diverso qui che dovrebbero essere affrontati. Il problema fondamentale sta cercando di elaborare un meccanismo che consente ad un oggetto arbitrario da inserire in un elenco esistente ad un certo punto nel mezzo di quella lista.

Non è descrivere ciò che l'interfaccia si presenta come IMetadataProvider, ma dovrebbe avere un modo per identificare in modo univoco un fornitore (opzione migliore sarebbe quella di utilizzare un GUID). Il vantaggio sopra utilizzando il nome della classe è che permette di rinominare le classi, se necessario durante il refactoring, ecc senza influenzare i fornitori (3a parte) personalizzati finché si mantiene il Guid lo stesso.

Invece di utilizzare un semplice elenco probabilmente si dovrebbe derivare il proprio elenco:

class ProviderList : List<IMetadataProvider { }

che espone un modo per un provider personalizzato (3a parte) per installare / disinstallare sé da quella lista. Questi meccanismi devono essere abbastanza intelligente per sapere come inserire il nuovo provider dentro al centro della catena, ma anche abbastanza intelligente per sapere come gestire molteplici provider personalizzati che sono stati inseriti. Allo stesso modo, il processo di rimozione deve essere intelligente come pure a che fare con simili preoccupazioni e anche assicurarsi che qualcuno non tenta di rimuovere uno dei vostri fornitori di "core".

Un buon approccio qui sarebbe probabilmente per passare il GUID del provider che si desidera essere inseriti dopo come parametro al metodo Install (). Il metodo Remove () dovrebbe parimenti prendere il GUID del provider da rimuovere.

Per esempio, dicono inserisco un nuovo fornitore dopo MovieProviderFromXml. Poi un altro 3a parte installa anche un nuovo fornitore dopo MovieProviderFromXml. Quale dovrebbe essere il nuovo ordine catena di essere? Ha il secondo fornitore di inserire sempre immediatamente dopo MovieProviderFromXml o vuol cominciare da lì e quindi saltare oltre qualsiasi provider personalizzati e inserire dopo l'ultimo provider personalizzato installato (così appena prima del prossimo provider "core"?

Related a questa domanda è l'idea che è necessario disporre di un modo per distinguere tra i vostri fornitori di "core" e un provider personalizzato.

Infine, è necessario assicurarsi che ci sia un modo per gestire gli errori nella catena, in particolare quando un provider personalizzato viene inserito nella posizione sbagliata.

Si può desiderare di mantenere sempre una base ( "master") l'elenco della vostra catena di default. Quando un nuovo fornitore è installato nel mezzo di quella catena, una nuova catena deve essere creato, ma non si vuole perdere la catena di base. Questo ti dà la possibilità di reimpostare la catena torna allo stato di default.

concatenamento in base alla priorità è problematico in quanto è quindi necessario stabilire come gestire le collisioni di priorità. Per quanto riguarda un Prima / Dopo impostare l'attributo, ti permettere sia sullo stesso fornitore? Probabilmente no, quindi potrebbe avere più senso per creare un ProviderChainAttribute che ha una proprietà ChainInsert enum, dove ChainInsert definisce Prima e dopo i valori di enum. Questo consente di forzare il provider personalizzato di fare una decisione se si installa prima di o dopo il provider specificato. Vorrei ancora usare un Guid piuttosto che il tipo.

Speriamo che questo ti dà alcune altre idee su come affrontare questo problema.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top