Pregunta

Puede una clase abstracta se utiliza como objeto de contrato entre un 'host' y un 'plug-in'? La idea es que el plugin hereda el contrato (lo llamamos un adaptador). También estamos entendiendo que todos los participantes en el marco deben heredar MarshalByRefObject (MBRO). Por lo tanto, esto es lo que estábamos pensando -

Host

class Host : MarshalByRefObject
{
}

contrato

public abstract class PluginAdapter : MarshalByRefObject
{
}

Plugin

class myPlugin : PluginAdapter
{
}

Los tres existen en asm de separado. Nuestro anfitrión va a crear un nuevo dominio de aplicación para cada plug-in, y se crea el PluginAdapter de la siguiente manera:

{
    ObjectHandle instHandle = Activator.CreateInstance(
    newDomain, data.Assembly.FullName, data.EntryPoint.FullName);

    PluginAdapter adapter = (PluginAdapter)instHandle.Unwrap();
}

editar . Donde data es el tipo concreto de myPlugin

Nos preguntamos si esta aplicación del marco funcionaría. Hemos visto artículos usando una interfaz (IPlugin) para la derivación plug-in, y una clase concreta como el contrato. Esos artículos también podrían decir que una clase abstracta se puede utilizar, pero no hay ejemplos de que la aplicación dada. ¿Se requiere que el contrato sea una clase concreta?

Editar : En este ejemplo por Richard Blewett - C # reflexión - se utiliza una aplicación mucho más simple:

contrato

public interface IPlugIn  
{  
    // do stuff  
}

Plugin

public class PlugIn : MarshalByRefObject, IPlugIn  
{  
}

Ahora, si se utiliza una clase abstracta como el contrato, el plugin no puede heredar tanto el contrato como MBRO. ¿Cuál es, entonces, se convierte en la mejor aplicación de un marco plug-in escalable. ¿Hay que seguir adelante y aplicar comunicación remota a pesar de que, en un principio, estamos desarrollando para la operación de una sola máquina? Se espera que este proyecto sea distribuido a través de una red, posiblemente a través de Internet también. Simplemente, no hemos implementado Tcp todavía porque estamos tratando de obtener las bases de un marco plug-in totalmente entendida y operativo.

¿Tiene sentido para implementar Tcp interacción remota en una sola máquina usando loopback?

¿Fue útil?

Solución

Las clases abstractas son mejores opciones para esto, en mi humilde opinión. Su principalmente porque las interfaces son más difíciles de versión. Esta entrada de blog describe el problema puede que te encuentres teniendo en el camino si no utiliza las clases de base. Esta regla no se aplica solamente a los plugins, por cierto.

Sobre el diseño de su ...

Los plugins no debe extenderse MBRO. Debe usar su anfitrión (que debería extenderse MBRO) a Marshall todas las llamadas a través de sus plugins, incluyendo el manejo de eventos plugin. Es muy fácil de cargar involuntariamente un plugin DLL en su dominio de aplicación principal si se intenta tirar de ellos a través y utilizar sus poderes.

Por ejemplo, si el plugin devuelve un IEnumerable para uno de sus métodos, puede devolver una implementación de IEnumerable que se define en el plugin montaje. Si eso no se extiende MBRO el dominio de aplicación principal tendrá que cargar el plugin de montaje.


He subido tres proyectos relacionados con dominios de aplicación aquí:

http: // cid -f8be9de57b85cc35.skydrive.live.com/self.aspx/Public/NET%20AppDomain%20Tests/appdomaintests.zip

Uno está utilizando devoluciones de llamada a través de dominios de aplicación, la segunda es el control de eventos transversal dominio de aplicación, y el tercero es un ejemplo plugin.

En el ejemplo plug-in, una aplicación define una interfaz de plug-in (es una demostración, no las mejores prácticas!) Y una gran cantidad de plugins. Las cargas de aplicaciones un plugin montaje en bruto de disco y lo pasa sobre al plugin dominio de aplicación a través del proxy anfitrión plugin, donde se carga. El plug-in de acogida entonces una instancia del plugin y lo utiliza. Pero cuando el anfitrión devuelve un tipo definido en el plugin conjunto de respaldo encima en el dominio de aplicación de aplicación, el plugin conjunto se carga en el dominio principal de la aplicación, rindiendo todo el asunto plugin de sentido.

Lo mejor de evitar esto es proporcionar una clase base abstracta para los plugins que no está marcado serializable y no se extiende MBRO, y sólo traen primitivas de espalda o tipos sellados que definen al otro lado de la frontera del dominio de plug-in.

Nota: los proyectos son todos 4.0 RC. Lo necesitará o superior para ejecutarlas. De lo contrario tendrá que editar los archivos de proyecto con la mano o reconstruirlas para conseguir que se ejecuta en B2 ó 2008.

Otros consejos

proporcionado "data.EntryPoint.FullName" es el nombre de tipo completo, el código anterior debería funcionar.

Sin embargo, si usted está tratando de mantener este tipo aislado en su propio dominio de aplicación, se debe tener cuidado aquí. Haciendo data.Assembly, se le tire del conjunto (y de los tipos es) en su dominio de aplicación, haciendo que los tipos sean cargados en el dominio de aplicación ejecutar ...

Es posible que desee echar un vistazo a MAF (el Marco complemento administrado) que es un marco de extensibilidad integrada en .NET para hacer complementos. Es similar (y mayores) que MEF (Managed Extensibility Framework) , pero tiene más opciones en cuanto a mantener plugins en su propio dominio de aplicación, entre otras cosas.

Si data.EntryPoint.FullName se refiere a la myPlugin tipo inmediato, no veo ninguna razón para que esto no funcionaría (a no ser que teniendo conjunto de carga de problemas en el otro dominio de aplicación, pero eso es otro tema).

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