Pregunta

Estoy añadiendo soporte plugin para mi aplicación .NET. Una clase base me suena razonable, por lo que las personas pueden heredarlo y anulación ciertas llamadas así pueden mantener la funcionalidad por defecto o pueden utilizar algunas funciones de ayuda interna.

¿Por qué elegir la interfaz en lugar de una clase de complemento de base para heredar? ¿Podría decir que el diseño debería elegir y por qué?

¿Fue útil?

Solución

Se debe considerar tomar un vistazo en el espacio de nombres System.AddIn (MAF) o en el marco de extensibilidad Gestionado (MEF). MEF sería la opción preferida a pesar de que todavía es pre-lanzamiento, ya que es mucho más simple que MAF. Cualquiera de esas opciones simplifican mucho el trabajo de plomería que tendrá que hacer con el fin de obtener los complementos cargados e interactuar con ellos.

En lo que hacer una elección entre una interfaz y una clase abstracta, si vas con MAF o algunas de MEF que se realizará para usted. Las diferencias más básicas en este contexto son que al proporcionar una clase base abstracta que proporciona un punto de herencia para plugins personalizados (escrito por usted o otros desarrolladores) y asegurarse de que ciertos métodos / propiedades proporcionan un comportamiento por defecto y obligan a las clases derivadas para implementar cierta necesarios métodos / propiedades. El inconveniente es que está limitado a una sola clase base.

Interfaces moverse por la limitación sola clase base y todavía proporcionan un punto de inhertiance para los plugins personalizados y asegurar que ciertos métodos / propiedades se implementan, pero no pueden proporcionar cualquier tipo de comportamiento por defecto. Tampoco se puede especificar que no sean miembros del público en una interfaz de nada, mientras que una clase abstracta puede tener miembros que no son públicas abstractas o virtuales (normalmente protegido).

Otros consejos

Utiliza una interfaz para el contrato plugin. Si un determinado tipo de plugin de acciones probables cierta funcionalidad, hacer una clase base abstracta que implementa la interfaz. También aseguran que sus contratos están en una asamblea fuera de su aplicación real.

Tenga en cuenta que en .NET, usted no tiene herencia múltiple. Exigir ejecutores a renunciar a su herencia ranura para proporcionar un poco de funcionalidad para ellos no es una buena idea.

¿Por qué tiene que ser uno o el otro?

Puede definir el contrato que los plugins deben seguir como una interfaz que se está haciendo referencia en todas partes.

Además, también se puede definir una clase base que implementa la interfaz, sino que simplemente tiene métodos abstractos que serán llamadas para algunas de las funciones de interfaz que no se puede proporcionar una implementación por defecto para.

public interface IPlugin
{
    void Initialize ();
    void Stuff ();
}

public class PluginBase : IPlugin
{
    protected abstract DoInitialize ();
    protected abstract DoStuff ();

    void IPlugin.Initialize { this.DoInitialize (); }
    void IPlugin.Stuff { this.DoStuff (); }
}

Hay un buen post sobre este tema aquí: API Plugin

Me gustaría utilizar una interfaz personalmente, y dejar que los plugins implementan todos los detalles.

Creo que lo más evidente que debe hacer es dejar que la devolución de llamada registro plug-in (delegados) para los eventos individuales que quiere manejar. Esta es la forma en la mayoría de los marcos de trabajo en .NET

En otras palabras, ni las clases de base ni interfaces. La ventaja de esta solución es que el plugin no tiene que ajustarse a cualquier interfaz externa dada o clase base, simplemente se registra para la funcionalidad que necesita.

A modo de ejemplo, las secciones "Eventos" en ningún control asp.net dada hace de esta manera: Tenga una mirada en UserControl

Algo que todo el mundo se olvida de mencionar es la compatibilidad hacia atrás. Se pueden añadir nuevos métodos a una clase base sin romper los clientes existentes, al tiempo que no puede modificar las interfaces existentes sin afectar a ellos.

Existen alternativas para evitar problemas de compatibilidad con interfaces. Por ejemplo, se podría crear una interfaz nueva que hereda de la anterior cuando se incluyen nuevas extensiones para su aplicación. Pero esto tiene el inconveniente de que su hinchazón arquitectura con tipos como IClientInterfaceV2 y IClientInterfaceV3.

Mi sugerencia personal sería ir con un enfoque como el sugerido por scwagner y crear tanto una clase base y una interfaz. E incluir una advertencia a los usuarios de la interfaz que indican que las futuras versiones podrían romper su aplicación y que la estrategia de la herencia de clases base es el recomendado para evitar futuros problemas de compatibilidad.

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