Question

une classe abstraite peut être utilisé comme objet de contrat entre un « hôte » et un « plug-in »? L'idée est que le plugin hérite du contrat (que nous appelons un adaptateur). Nous comprenons également que tous les participants dans le cadre doivent hériter MarshalByRefObject (MBro). Donc, ce que nous pensions -

Host :

class Host : MarshalByRefObject
{
}

Contrat :

public abstract class PluginAdapter : MarshalByRefObject
{
}

Plugin :

class myPlugin : PluginAdapter
{
}

Les trois existent dans les années asm séparés. Notre hôte créera un nouveau AppDomain pour chaque plug-in, et le PluginAdapter est créé comme suit:

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

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

EDIT :. Où data est le type de béton myPlugin

Nous nous demandions si cette mise en œuvre du cadre fonctionnerait. Nous avons vu des articles en utilisant une interface (IPlugin) pour la dérivation de plug-in, et une classe concrète que le contrat. Ces articles diraient aussi qu'une classe abstraite peut être utilisé, mais pas d'exemples de cette mise en œuvre donnée. Est-il nécessaire que le contrat soit une classe concrète?

EDIT : Dans cet exemple par Richard Blewett - C # réflexion - il utilise une implémentation beaucoup plus simple:

Contrat :

public interface IPlugIn  
{  
    // do stuff  
}

Plugin :

public class PlugIn : MarshalByRefObject, IPlugIn  
{  
}

Maintenant, si vous utilisez une classe abstraite que le contrat, le plug-in ne peut pas hériter à la fois le contrat et MBro. Que devient alors la meilleure mise en œuvre d'un cadre de plug-in évolutif. Faut-il aller de l'avant et mettre en œuvre Remoting même si, au départ, nous développons pour le fonctionnement d'une seule machine? Ce projet devrait se répartir à travers un réseau, peut-être à travers l'Internet aussi bien. Nous avons tout simplement pas encore mis en œuvre Tcp parce que nous essayons d'obtenir les bases d'un cadre de plugin bien compris et opérationnel.

Est-il judicieux de mettre en œuvre Remoting Tcp sur une seule machine en utilisant réalimentation?

Était-ce utile?

La solution

Les classes abstraites sont de meilleurs choix pour cela, à mon humble avis. Ses principalement parce que les interfaces sont plus difficiles à la version. Ce billet de blog décrit la question que vous pourriez vous retrouver ayant sur la route si vous ne pas utiliser les classes de base. Cette règle ne concerne pas seulement les plug-ins, btw.

A propos de votre conception ...

Plugins ne doivent pas étendre MBro. Vous devez utiliser votre hôte (qui devrait étendre MBro) à marshall tous les appels à travers vos plug-ins, y compris la gestion des événements de plug-in. Il est très facile à charger involontairement une DLL de plug-in dans votre principale appdomain si vous essayez de les tirer à travers et utiliser leurs mandataires.

Par exemple, si le plugin retourne un IEnumerable pour une de ses méthodes, il peut renvoyer une mise en œuvre de IEnumerable qui est défini dans l'ensemble de plug-in. Si cela ne s'étend pas MBro le principal appdomain devra charger l'ensemble de plug-in.


J'ai uploadé trois projets traitant de domaines d'application ici:

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

On utilise callbacks à travers AppDomains, le second cross-appdomain la manipulation et le troisième est un exemple plugin.

Dans l'exemple plug-in, une application définit une interface de plug-in (une démo de son, pas les meilleures pratiques!) Et un hôte de plug-in. L'application d'une charge brute d'assemblage de module à partir du disque et le transmet vers le module appdomain via le proxy hôte de plug-in, où il est chargé. L'hôte de plug-in, puis le plugin instancie et utilise. Mais quand l'hôte retourne un type défini dans l'ensemble de plug-in dans le dos sur appdomain d'application, l'ensemble de plug-in est chargé dans le domaine d'application principal, ce qui rend la chose plugin inutile.

La meilleure chose pour éviter cela est de fournir une classe de base abstraite pour les plugins qui ne sont pas marqués sérialisable et ne se prolongent pas MBro, et seulement ramener primitives ou types scellés, vous définissez retraverser la frontière du domaine de plug-in.

NOTE: les projets sont 4.0 RC. Vous en aurez besoin ou au-dessus pour les exécuter. Sinon, vous devrez modifier les fichiers du projet à la main ou les reconstruire pour les faire fonctionner en b2 ou 2008.

Autres conseils

fourni "data.EntryPoint.FullName" est le nom du type complet, le code ci-dessus devrait fonctionner.

Cependant, si vous essayez de garder ce type isolé dans son propre AppDomain, vous devriez faire attention ici. En faisant data.Assembly, vous tirez l'ensemble (et il est types) dans votre AppDomain, ce qui provoque les types à charger dans l'exécution AppDomain ...

Vous pouvez jeter un oeil à CRG (Cadre Addin géré) qui est un cadre d'extensibilité intégré dans .NET pour faire Addins. Il est similaire (et plus) que MEF (Managed Extensibility Framework) , mais a plus d'options dans la mesure du maintien plugins dans leur propre domaine d'application, entre autres.

Si data.EntryPoint.FullName fait référence au type de béton myPlugin Je ne vois aucune raison pour laquelle cela ne fonctionnerait pas (à moins que d'avoir des problèmes de chargement de montage dans l'autre appdomain mais c'est une autre question).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top