Pregunta

Navegador de medios tiene un modelo de proveedor, esto es básicamente una cadena de clases que serán llamadas en un orden determinado para cada entidad.

Así por ejemplo tenemos:

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

El orden de los proveedores en la lista es significativos mayores proveedores de orden prevalecen sobre los de orden inferior.

Recientemente, he tratado de hacer esta parte extensible. Así que una tercera parte de DLL puede definir sus propios proveedores que conseguirá inyectados en nuestra cadena.

El problema es que una vez que usted permite a 3 partes para inyectarse a sí mismos en la cadena se pierde un lugar central para definir este orden.

Mi solución actual que estoy un poco incómodo con es definir un atributo de prioridad opcional con cada proveedor y luego por el orden de prioridad.

Así, por ejemplo ahora tengo:

[ProviderPriority(20)]
class ImageByNameProvider{}

Esto permite que 3 partes para definir su posición en la cadena.

Otra de las soluciones que pensé eran antes y después de atributo Ej.

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

Sin embargo, no estoy seguro de si es fácil o más difícil de programar en contra.

¿Hay otras soluciones para este problema? ¿Qué solución le ir?

Tal vez, yo debería mantener la lista de los proveedores principales y añadir el antes / después attribs para los proveedores de terceros ...

¿Fue útil?

Solución

Parece que en realidad hay algunas cuestiones diferentes aquí que deben ser abordados. El problema fundamental está tratando de llegar a un mecanismo que permite a un objeto arbitrario que se insertará en a una lista existente en algún punto en el medio de esa lista.

No es describir lo que la interfaz IMetadataProvider en realidad se parece, pero debe tener alguna forma de identificar de forma única a un proveedor (mejor opción sería utilizar un GUID). El beneficio sobre el uso del nombre de la clase es que permite cambiar el nombre de las clases según sea necesario durante la refactorización, etc., sin afectar proveedores personalizados (tercera parte), siempre y cuando mantenga el Guid la misma.

En lugar de utilizar una lista simple que probablemente debería derivar su propia lista:

class ProviderList : List<IMetadataProvider { }

que expone una manera para que un proveedor personalizado (tercera parte) para instalar / desinstalar sí de esa lista. Estos mecanismos tienen que ser lo suficientemente inteligente para saber cómo insertar el nuevo proveedor en el centro de la cadena, pero también lo suficientemente inteligente para saber cómo manejar varios proveedores personalizados que han sido insertados. Del mismo modo, el proceso de eliminación tiene que ser inteligente, así que tratar con preocupaciones similares y también asegurarse de que alguien no trata de eliminar uno de sus proveedores de "núcleo".

Un buen enfoque sería probablemente aquí para pasar el GUID del proveedor que desea insertar después como un parámetro para el método Instalar (). El método Remove () sería igualmente tomar el GUID del proveedor para ser eliminado.

Por ejemplo, dicen que inserte un nuevo proveedor después de MovieProviderFromXml. Luego, otra tercera parte también instala un nuevo proveedor después de MovieProviderFromXml. ¿Cuál debe ser el nuevo orden de la cadena? ¿El segundo proveedor siempre insertar inmediatamente después de MovieProviderFromXml o se inicia allí y luego saltar más allá de cualquier proveedor personalizados e insertar después de instalado el último proveedor personalizado (por lo que justo antes del siguiente proveedor de "núcleo"?

En cuanto a esa pregunta es la idea de que es necesario tener alguna forma de distinguir entre sus proveedores de "núcleo" y un proveedor personalizado.

Por último, es necesario asegurarse de que hay una manera de manejar fallos en la cadena, sobre todo cuando se inserta un proveedor personalizado en el lugar equivocado.

Usted desea mantener siempre una base ( "maestro") la lista de su cadena por defecto. Cuando un nuevo proveedor se instala en el centro de esa cadena, una cadena nueva debe crearse pero no quiere perder la cadena de base. Esto le da la capacidad de restablecer la cadena de nuevo al estado por defecto.

El encadenamiento basado en la prioridad es problemático, ya que luego hay que determinar cómo manejar las colisiones prioritarios. En lo que a Antes / Después de establecer el atributo, habría que permitir que tanto en el mismo proveedor? Probablemente no, por lo que podría tener más sentido para crear un ProviderChainAttribute que tiene una propiedad ChainInsert enumeración, donde ChainInsert define antes y después como valores de enumeración. Esto le permite forzar el proveedor personalizado para tomar una decisión en cuanto a si se instala antes de o después de que el proveedor especificado. Me gustaría volver a usar un GUID en lugar del tipo.

Esperamos que esto le da algunas otras ideas sobre cómo abordar este problema.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top