Frage

Kann eine abstrakte Klasse, die als Vertragsgegenstand zwischen einem ‚Host‘ und eine ‚Plugin‘ verwendet werden? Die Idee ist, dass das Plugin den Vertrag erbt (wir nennen es einen Adapter). Wir verstehen auch, dass alle Teilnehmer im Rahmen MarshalByRefObject erben müssen (MBRO). Also, das ist, was wir denken -

Host :

class Host : MarshalByRefObject
{
}

Vertrag :

public abstract class PluginAdapter : MarshalByRefObject
{
}

Plugin :

class myPlugin : PluginAdapter
{
}

Alle drei exist in getrennter asm ist. Unser Gastgeber wird eine neue AppDomain für jedes Plugin erstellen, und die PluginAdapter wird wie folgt erstellt:

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

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

Bearbeiten . Wo data ist die konkrete Art der myPlugin

Wir fragten uns, ob diese die Umsetzung des Rahmen funktionieren würde. Wir haben Artikel gesehen eine Schnittstelle (IPlugin) für das Plugin Ableitung verwendet wird, und eine konkrete Klasse, die als Vertrag. Diese Artikel würden auch sagen, dass eine abstrakte Klasse verwendet werden kann, aber keine Beispiele für diese Umsetzung gegeben. Ist es erforderlich, dass der Vertrag eine konkrete Klasse sein?

Bearbeiten : In diesem Beispiel von Richard Blewett - C # Reflection - er verwendet eine viel einfachere Implementierung:

Vertrag :

public interface IPlugIn  
{  
    // do stuff  
}

Plugin :

public class PlugIn : MarshalByRefObject, IPlugIn  
{  
}

Nun, wenn eine abstrakte Klasse, die als Vertrag verwendet, kann das Plugin sowohl den Vertrag nicht und MBRO erbt. Was also wird die beste Implementierung für ein skalierbares Plugin-Framework. Sollten wir, obwohl gehen Sie vor und implementieren remoting, zunächst entwickeln wir für Einzelmaschinenbetrieb? Dieses Projekt wird voraussichtlich über ein Netzwerk verteilt werden, möglicherweise über das Internet als auch. Wir haben einfach nicht umgesetzt Tcp noch, weil wir versuchen, die Grundlagen eines Plugin-Framework zu bekommen vollständig verstanden und in Betrieb genommen.

Ist es sinnvoll Tcp Remoting auf einer einzigen Maschine zu implementieren Loopback verwenden?

War es hilfreich?

Lösung

Abstrakte Klassen gibt bessere Alternativen für diese, imho. Sein erster Linie, weil Schnittstellen sind schwerer zu Version. Dieser Blog-Eintrag das Problem beschrieben, die Sie selbst finden könnte wenn Sie Basisklassen nicht verwenden auf der Straße haben. Diese Regel gilt nicht nur für Plugins gelten, btw.

über Ihr Design ...

Plugins sollte nicht MBRO erweitern. Sie sollten Ihren Host (was sollte erweitern MBRO) zu marshall alle Anrufe über zu Plugins, einschließlich Umgang mit Plug-Ereignisse verwenden. Es ist sehr einfach zu unbeabsichtigt ein Plugin-DLL in Ihr Haupt Appdomain zu laden, wenn Sie sie über zu ziehen versuchen und ihre Proxies verwenden.

Zum Beispiel, wenn das Plugin einen IEnumerable für eine seiner Methoden gibt, kann es eine Implementierung von IEnumerable zurück, die Montage im Plugin definiert ist. Wenn das nicht MBRO die Haupt Appdomain verlängern Montage das Plugin zu laden haben.


Ich habe zu tun drei Projekte hochgeladen mit AppDomains hier:

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

Man ist Rückrufe über AppDomains verwendet wird, ist die zweite Quer Appdomain Ereignisbehandlung und der dritte ist ein Plugin Beispiel.

Im Plugin Beispiel definiert eine Anwendung einen Plugin-Schnittstelle (seine eine Demo, nicht Best Practices!) Und eine Plugin-Host. Die App lädt Plugin eine Montage roh von der Festplatte und gibt sie über an das Plugin Appdomain über das Plugin Host-Proxy, von dem es geladen wird. Der Plugin-Host instanziiert dann das Plugin und verwendet es. Aber wenn der Host kehrt ein Typ in der Plugin definiert Baugruppe wieder über in die Anwendung Appdomain, die Plug-Montag in die Hauptanwendungsdomäne geladen wird, die ganze Plugin Sache sinnlos machen.

Das Beste, was dies zu vermeiden, ist eine abstrakte Basisklasse für Plugins bieten, die nicht serialisierbar gekennzeichnet ist und erstreckt sich nicht MBRO, und nur zurückbringen Primitiven oder versiegelte Typen, die Sie definieren, über die Grenze aus dem Plugin-Domäne zurück.

Hinweis: die Projekte sind alle 4.0 RC. Sie werden diese benötigen oder über ihnen zu laufen. Sonst wirst du zu bearbeiten haben die Projektdateien von Hand oder neu erstellen sie sie in b2 oder 2008 zum Laufen zu bringen.

Andere Tipps

Sofern "data.EntryPoint.FullName" ist der vollständige Typname, sollte der obige Code arbeiten.

Allerdings, wenn Sie versuchen, diese Art in einem eigenen AppDomain isoliert zu halten, sollten Sie vorsichtig sein, hier. Dadurch data.Assembly, werden ziehen Sie die Baugruppe (und es ist Typ) in Ihrem AppDomain, so dass die Typen in der Ausführung AppDomain ...

geladen werden

Sie können einen Blick auf MAF (der Managed AddIn Framework) nehmen wollen , die ein erweiterbares Framework eingebaut in .NET für Add-in zu tun. Es ist ähnlich (und älter) als MEF (Managed Extensibility Framework) , aber mehr Optionen, soweit Haltung hat Plugins in ihrer eigenen Anwendungsdomäne, unter anderem.

Wenn data.EntryPoint.FullName zum myPlugin konkreter verweist ich sehe keinen Grund, warum dies nicht funktionieren würde (es sei denn, als wenn Montag Probleme in der anderen Appdomain geladen, aber das ist ein anderes Thema).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top