.
Anmeldung | Registrieren | Hilfe
in Suchen

Plugin Anwendung mit System.AddIn

Letzter Beitrag 20. Okt 2008 18:51 von karle. 6 Antworten.
Seite 1 von 1 (7 Treffer)
Beiträge sortieren: Zurück Weiter
  • 20. Okt 2008 10:18

    • jusuf12
    • Top 500 Mitwirkender
    • Registriert am 20. Okt 2008
    • Erlangen
    • Beiträge 3
    • Punkte 60

    Plugin Anwendung mit System.AddIn

    Hallo zusammen,

    eventuell kann mir ja einer der Profis weiterhelfen. Ich bastel gerade an einer Pluginanwendung und habe mir mal das neue System.AddIn in .Net 3.5 angesehen. Das macht ja alles mal einen guten Eindruck, aber wie können denn hier die einzelnen Plugins untereinander kommunizieren? Ich habe mir gedacht, ich nehme den Host nur als Vermittler, der dann das "Empfängerplugin" als Referenz an das "Senderplugin" übergibt. Per Reflection könnten dann die Methoden auf dem Empfänger aufgerufen werden. Irgendwie stelle ich mich aber zu dämlich an, um das zu implementieren. Vielleicht könnte mir jemand einen Tipp bezüglich der Erstellung des Contracts und der Adapter geben.

    Danke schon mal.

    Harry
    • IP-Adresse ist Registriert
  • 20. Okt 2008 10:38 Antwort zu

    • Gordon Breuer
    • Top 10 Mitwirkender
      Männlich
    • Registriert am 04. Jun 2008
    • Frankfurt a.M.
    • Beiträge 344
    • Punkte 5.750
    • Moderator

    Plugin Anwendung mit System.AddIn

    Die Kommunikation geschieht über eine so genannte Pipeline mit einem Contract. Hierfür gibt es auch ein kleines kostenloses Tool, den Pipeline-Builder. Den und zahlreiche Beispiele findest du auf Codeplex: http://www.codeplex.com/clraddins

    Es gibt auch noch 2 interessante, kurze Webcasts zu dem Thema - allerdings nur auf englisch. Sind aber sehr empfehlenswert und bietet einen guten Einstieg in die Addin-Entwicklung. Smile (*Link hierzu reiche ich später nach*)

    • IP-Adresse ist Registriert
  • 20. Okt 2008 10:55 Antwort zu

    Plugin Anwendung mit System.AddIn

    Hier gibt es noch einen Artikel auf Codeproject von Sacha Barber (http://www.codeproject.com/KB/dotnet/AddInModel.aspx). Vielleicht hilft der dir auch weiter.

    Den groben Aufbau wirst du sicher schon kennen. Ansonsten frag nochmal nach, dann skizziere ich es kurz.

    Gruß,
    Rainer
    • IP-Adresse ist Registriert
  • 20. Okt 2008 10:55 Antwort zu

    • jusuf12
    • Top 500 Mitwirkender
    • Registriert am 20. Okt 2008
    • Erlangen
    • Beiträge 3
    • Punkte 60

    Plugin Anwendung mit System.AddIn

    Hallo,
    vielen Dank erstmal. Aber die Kommunikation zwischen Host und AddIn funktioniert schon.
    Wenn jetzt aber die Plugins untereinander kommunizieren können sollen, klappt der Ansatz ja nicht mehr so einfach. Man müsste ja dann eine Pipeline zwischen den AddIns aufbauen. Deshalb war meine Idee, dass der Host eine Art Registry der Plugins zur Verfügung stellt. Ein AddIn kann sich dann vom Host den gewünschten Partner geben lassen und direkt mit ihm sprechen. Um jetzt aber nicht jedesmal einen Contract für ein neues, zu übergebendes Plugin erstellen zu müssen, habe ich an die Verwendung von Reflection gedacht. Eventuell ist es ja so möglich  ohne Änderung des Contracts die neue Schnittstelle zu nutzen.
    Und genau da hakt es bei mir aus. Es gibt zwar anscheinend diese Möglichkeit (System.AddIn.Contract.Automation IRemoteObjectContract) aber ich habe keine Ahnung, wie das zu Verwenden ist. Beispiele habe ich auch noch keine gefunden.

    Harry


    [Edit:]

    Vielen Dank. Hier kommen ja die Antworten schneller, als ich Tippen kann ;-)
    • IP-Adresse ist Registriert
  • 20. Okt 2008 15:20 Antwort zu

    Plugin Anwendung mit System.AddIn

    Das ist denke ich so auch gar nicht vorgesehen, dass Addins miteinander Kommunizieren.
    Ich war auf der BASTA in der Session zu System.Addin.

    So wie ich das noch in Erinnerung habe wird die Kommunikation zu "Fenstern" hin über einen Trick durchgeführt. Vom jeweiligen Fenster wird das Handle (good old Win32) als IntPtr über die Pipeline getunnelt. In der nächsten Version soll es hier auch nochmal Änderungen geben.

    Du könntest z.B. ein Kommunikationsinterface erstellen, dass einen Kommunikationsdienst zur Verfügung stellt.

    Vielleicht ist der Ansatz, den du verfolgst auch gar nicht mit System.AddIn sinvoll umsetzbar. Unter Umständen wäre eine Lösung über einen Dependency Injection Container besser?


    • IP-Adresse ist Registriert
  • 20. Okt 2008 15:37 Antwort zu

    • jusuf12
    • Top 500 Mitwirkender
    • Registriert am 20. Okt 2008
    • Erlangen
    • Beiträge 3
    • Punkte 60

    Plugin Anwendung mit System.AddIn

    Ich denke auch langsam, dass das so nicht funktionieren wird. Die Probleme gehen ja noch weiter. Um zum Beispiel einzelne Menuitems einzubauen, die vom Plugin mitgebracht werden, müsste ich für die eine eigene Klassen schreiben beziehungsweise für alle einen Contract anlegen.
    Komplette Fenster werden per win32 Handle referenziert. Das stimmt.
    An ein Kommunikationsinterface habe ich auch schon gedacht. Ich wollte eigentlich einzelne Commands(selber serialisiert) an die AddIns versenden, mit dem Host als Dispatcher, allerdings funktioniert das nur mit Kopien. Das wiederrum bringt dann aber Probleme mit Inkonsistenzen, zum Beispiel bei einem Datenbankplugin mit sich.
    Ich habe jetzt mal angefangen, die Struktur selber aufzubauen. Mal sehen, wie weit ich damit komme ;-)
    Eventuell kann ich ja einen .Net Remoting Proxie mit einbauen.

    • IP-Adresse ist Registriert
  • 20. Okt 2008 18:51 Antwort zu

    • karle
    • Top 25 Mitwirkender
    • Registriert am 20. Okt 2008
    • Beiträge 177
    • Punkte 2.070

    Plugin Anwendung mit System.AddIn

    Zitat: Das ist denke ich so auch gar nicht vorgesehen, dass Addins miteinander Kommunizieren.

    Hehe, genau das szenario habe ich aber auch. (Siehe Thema "Plugin Anwendung ohne System.AddIn")

    Ich glaube aber, dass es so abwegig nicht ist, das zu tun: Wenn man das Plugin als Komponente eines skalierbaren Systems sieht ist glaub nicht unbedingt realisierbar, dass der Anwendungsrahmen für jede Anwendung eine Interceptor-Strategie bereit stellt. (Das würde den Plugin-Rahmen vielleicht unnötig konkretisieren) Da will man Plugins installieren können, die als Vermittler zwischen anderen Plugins agieren und dazu natürlich mit denen kommunizieren müssen. Nungut, das ist eine andere Diskussion.

    Was ich jedenfalls gemacht habe, um das zu realisieren (auch wenn das laut Microsoft böse oder nicht unterstützt ist):

    Eine Dependency-Injection zu realisieren:

    - Wenn Plugin2 auf Plugin1 zugreifen möchte:

    - Neben Plugin1 und Plugin2 ein Projekt "Plugin1Services" zu definieren.

    - Dort wo die Plugins geladen werden stellt man ein System.Dictionary(Of System.Type, IServiceBase) Objekt bereit, in das Plugins ihre Services eintragen können, bzw. von der Plugins Services abfragen können. =>Kardinalität: Eine ServiceMap, mehrere Plugins. Die sieht z.b. so aus:

    Public Class Class CServices
    
    
       Private Items As New System.Collections.Generic.Dictionary(Of System.Type, IServiceBase)
    
    
       Public Sub AddService(Of TService)(ByVal aService As IServiceBase)
    
    
          Me.Items.Add(GetType(TService), aService)
    
    
       End Sub
    
    
       Public Sub GetService(Of TService) As TService
    
    
          Return DirectCast(Me.Items.Item(GetType(TService)), TService)
    
    
       End Sub
    
    
    End Class

    - Man kann auch die System.ComponentModel definierten Klassen verwenden, die folgen auch dem Dependency-Injection-Muster - die map muss man aber glaub auch da selber definieren.

    - Falls man den System.AddIn verwendet kann man den PluginKontext vermutlich nicht erweitern. Dann kann man die ServiceMap immer noch als singleton definieren.

    - In Plugin1Services definiert man ein IPlugin1Service interface, das von IServiceBase erbt

    Public Interface IPlugin1Service
    
    
       Inherits IServiceBase
    
    
       Sub DoSomething()
    
    
    End Interface

    - Plugin1 implementiert diesen Service und registriert ihn, wenn das Plugin geladen wird. z.b.

    Public Class CPlugin1
    
    
       Inherits CPluginBase
    
    
       Implements IPlugin1Service
    
    
       Public Overrides Sub LoadPlugin(ByVal aPluginContext As CPluginContext)
    
    
          aPluginContext.Services.AddService(Of IPlugin1Service)(Me)
    
    
          Me.PluginContext = aPluginContext
    
    
       End Sub
    
    
    End Class

    - Plugin2 fragt den service ab; im einfachsten fall während der Anwendungslaufzeit, wenn er benötigt wird.

    Me.PluginContext.Services.GetService(Of IPlugin1Service).DoSomething

    - Der schwierigere Fall ist, wenn man für die Registrierung eines Plugins Services anderer Plugins benötigt oder Plugins auf ereignisse anderer Services reagieren möchten. Ich habe mir mit zwei Methoden beholfen: RegisterComponents und RegisterDependencies. Zuerst wird für alle Plugins RegisterComponents ausgeführt, dannach für alle Plugins RegisterDependencies. In RegisterDependencies kann man sich darauf verlassen, dass alle Services vorhanden sind.

    - Wer seine Plugins zur laufzeit laden und entladen möchte muss zur registrierung bzw. aktualisierung der service-abhängigkeiten auf ein Ereigniss 'OnLoadPlugin' und 'OnUnloadPlugin' des Plugin-Rahmens hören.

    - Das funktioniert soweit wunderprächtig.

    - Aufpassen muss man, wenn man auf die Entkopplung über die Service-Interfaces verzichten möchte und zb. Plugin2 direkt Typen von Plugin1 verwenden will. Dann kommt es leicht zu dem Problem doppelt geladener Assemblies und daraus resultierender Type-Cast-Fehler. (Siehe Thema "Plugin Anwendung ohne System.AddIn") Ich vermute ja schwer, dass es dazu auch unter Verwendung von System.AddIn kommt. Zumal die Kommunikation unter AddIns ja nicht vorgesehen ist (also bidddööö)

    karle

    In meinem Keller ist der Eingang zur Hölle - aber es stehen Kartons davor.
    • IP-Adresse ist Registriert
Seite 1 von 1 (7 Treffer)

WPF Forum | ASP.NET Forum | ASP.NET MVC Forum | Silverlight Forum | Windows Phone 7 Forum | SharePoint Forum | Dotnet Jobs | Dotnet Termine | Developer Blogs | Dotnet News

Das Team | Regeln | Impressum