2009-11-18 11 views
5

Una vez resuelto el problema de cargar complementos (en .NET a través de MEF en el caso), el siguiente paso para resolver es la comunicación con ellos. La forma más simple es implementar una interfaz y usar la implementación del complemento, pero a veces el complemento solo necesita extender la forma en que funciona la aplicación y puede haber muchos puntos de extensión.Arquitectura para la extensión/comunicación del complemento

Mi pregunta es acerca de cómo lidiar con esos puntos de extensión. He visto diferentes maneras de hacerlo, pero no estoy seguro de los pros y los contras de cada uno y si hay más y mejores maneras de lograr esto:

  • Eventos: Adición de eventos estáticos a todas las cosas queremos hacer "extensible". Por ejemplo, si deseo agregar una validación personalizada para una clase de usuario, puedo agregar un controlador de evento estático OnValidation y agregarle eventos desde el complemento cuando se construya.
  • Mensajería: Tener un bus y un mensaje. El complemento puede suscribirse a un mensaje en particular y hacer cosas cuando otra clase lo publique. El mensaje debe contener el contexto en el que el complemento puede funcionar. En el caso de validación, la capa lógica publicará un mensaje de validación de usuario y el complemento actuará cuando se reciba el mensaje.
  • Interfaces: la aplicación de host es responsable de llamar a todos los complementos que implementan ciertas interfaces y darles el contexto de la operación actual. En el caso de la validación, el complemento puede implementar un IValidator o IUserValidator con un método de validación (contexto del objeto).

¿Alguna vez ha utilizado uno de los enfoques expuestos? ¿Cuál funcionó mejor para ti?

Y antes de preguntar, nuestra aplicación es un núcleo extensible (usuario, rola y gestión de contenido) para construir nuestras aplicaciones web centradas en el contenido específicas del cliente además de eso. Todo construido en ASP.NET MVC.

Respuesta

2

Una clave para su decisión de diseño es analizar y obtener una idea clara de cuán diferentes serán los complementos entre sí.

E.g. cuando se trata de eventos estáticos, probablemente tendrá que definir cada evento como una forma de token, enum, object etc. Tener que definir un nuevo conjunto de eventos para cada complemento funciona naturalmente en contra de su diseño completo, particularmente en términos de acoplamiento flexible y reutilizar.

Si sus complementos son muy diferentes, puede beneficiarse de tener una arquitectura de bus/mensajería ya que en tal caso puede introducir dominios/categorías de intercambio de comunicación, a los que los complementos pueden suscribirse. Es decir. una gama de eventos y mensajes puede estar en un cierto dominio de interés. Tenga en cuenta que la comunicación dentro de una categoría determinada todavía puede utilizar eventos estáticos, por lo que esas dos alternativas no son mutuamente excluyentes.

Las interfaces directas implementadas por los complementos es en mi experiencia el enfoque más estricto de la arquitectura de los complementos. La extensión de la interfaz del complemento generalmente implica la modificación del código tanto en el complemento como en el proveedor. Necesita tener una interfaz general sólida que sepa que su aplicación puede vivir por bastante tiempo.

Puede ser más fácil para usted para hacer frente con el diseño dividiéndola en dos aspectos - canal de comunicación y protocolo. El manejo de eventos estáticos es un problema de protocolo, mientras que la mensajería de bus y las interfaces directas son un problema de canal.

En general, diría que el protocolo es el más difícil de diseñar correctamente desde el principio, ya que es posible que no tenga una idea sólida de qué tan general o específico puede trazar la línea.

EDIT: Lars hizo un punto importante en su comentario - si su plataforma admite excepciones, puede centralizar una gran parte del manejo de errores al usar interfaces directas, el alivio de los plugins de tener que manejar los errores que son genéricas y tal vez outisde su dominio particular (por ejemplo, "error de carga del complemento" o "error de archivo abierto"). Sin embargo, tales beneficios parecerán desvanecerse si tiene que mantener las interfaces cada vez que agrega complementos. El peor caso es cuando las interfaces comienzan a volverse inconsistentes en el camino porque no se dio cuenta de lo que deberían apoyar desde el principio. Refactorizar todo el diseño de la interfaz cuando ya se ha concebido una cantidad considerable de complementos no es una tarea fácil.

+0

Las interfaces probablemente serían mi enfoque, aunque depende de la aplicación y sus necesidades de complementos. Pero es una forma muy limpia de hacer complementos, y también será fácil aislar excepciones del complemento. –

0

Me gustaría ir con el Observer patrón. Desde el Gobierno de Francia:

definir una dependencia de uno-a-muchos entre los objetos de manera que cuando uno cambios objeto de estado de todos sus dependientes son notificados y actualizados automáticamente.

También conocido como publish-subscribe, sugeriría que se parezca más al caso dos en sus ejemplos.

+0

En mi humilde opinión, el patrón del observador está un nivel por encima de este problema. Es decir. todas las alternativas que presenta encajarían en ese patrón. El problema que nos ocupa tiene que ver con la decisión específica de implementación del patrón de observador. – sharkin

+0

Al leer nuevamente y con una mayor digestión, creo que probablemente sea correcto R.A. – Martin

Cuestiones relacionadas