Entwickler-Ecke

Basistechnologien - UserControl aus dll laden


delphisual - Sa 24.11.07 14:24
Titel: UserControl aus dll laden
Hallo zusammen,
ich bin noch nicht so fit im C# und würde gerne erfahren ob meine Idee realisierbar ist.

Folgende Situation:
Ich habe eine Dll mit einem UserControl nun möchte ich, dass eine andere Anwendung diese Dll lädt und dieses UserConrol visualisiert. Man stelle sich vor es gibt viele Dlls die einen UserControl anbieten und je nachdem welche Dll geladen wird, sieht man den UserControl der geladenen Dll.

Hat jemand vielleicht eine Idee wie man dabei vorgeht?

Vielen Dank
delphisual


Kha - Sa 24.11.07 19:27

Nicht gerade das einfachste Problem. Eine Lösung wäre die Plugin-API von .Net 3.5, das könnte aber schon wieder Overkill sein.
Per Hand würde ich so vorgehen:

Geladene Assemblies können allerdings nicht mehr entladen werden (das ginge nur per AppDomains).


delphisual - Sa 24.11.07 23:26

Danke Khabarakh für diesen interessanten Vorschlag, schade diese Assemblies nicht mehr entladbar sind. Mein Lösungsansatz wäre es in jede Dll eine Funktion zu implementieren die den richtigen UserControl-Namen zurückgibt.

Leider sehe ich bei den C#-Dlls bestimmte Nachteile im Vergleich zu den Dlls die in C, C++ geschrieben werden: Die Beispiele, die ich bis jetzt für C#-Dlls gefunden habe zeigen mir, dass die Anwendung, die diese Dll lädt schon beim kompilieren auf die Dll referenzieren muss. Eine C#-Anwendung kann zwar C, C++ Dlls laden aber dann kann ich ja direkt bei C++ bleiben. Oder kann mir hier jemand sagen wie ich so was in C#-Dll implementiere(Beispiele sind aus MSDN C#-Anwendung lädt eine c-dll):


C#-Quelltext
1:
2:
3:
4:
5:
// c-dll 
int __declspec(dllexport) SampleMethod(int i) //Schade, dass das nicht unter c# geht ;-(
{
    return i*10;
}



C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
//c#-Anwendung
using System;
using System.Runtime.InteropServices;
public class MainClass 
{
    [DllImport("Cmdll.dll")]
    public static extern int SampleMethod(int x);
    static void Main() 
    {
        Console.WriteLine("SampleMethod() returns {0}."
                SampleMethod(5));
    }
}


Unter C# muss ich wahrscheinlich so vorgehen, was sehr unflexibel ist:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
// c#-dll  
namespace CSharp.Introduction  
{  
   public class HelloMessage  
   {  
      public string Message 
      {  
         get 
         {  
            return "hello, world";  
         }  
      }  
   }  
}



C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
// c#-Anwendung
using CSharp.Introduction;  // namespace der Dll
class HelloApp  
{  
   static void Main() 
   {  
      HelloMessage m = new HelloMessage();  
      System.Console.WriteLine(m.Message);  
   }  
}


Wer kann helfen das Problem umzugehen oder hat einen alternativen Vorschlag?


Kha - Sa 24.11.07 23:52

Dein Code ist ein Beispiel statischer Bindung, wie du schon selbst gesagt hast. Dynamische Bindung habe ich oben (kurz) beschrieben. Es mag mit .Net nicht so einfach sein, schnell mal eine einzelne Funktion dynamisch zu binden - wie oft man so etwas braucht, ist aber fraglich, letztendlich läuft es wohl immer auf ein Plugin-Framework hinaus. Und auch wenn ich das neue Dingens im 3.5er Framework noch nicht ausprobiert habe, dürfte es allein durch solche .Nettigkeiten wie Versioning, AppDomains und Attribute C++-Lösungen klar überlegen sein.


Christian S. - Sa 24.11.07 23:57

Kannst Du mir einen Link zu dem "Dingens" in 3.5 geben? Würde mir das gerne mal ansehen. :-)

//edit: Ah, hab schon was gefunden, von dem aus ich mich "weiterhangeln" kann: http://msdn2.microsoft.com/en-us/arcjournal/bb735304.aspx


Kha - So 25.11.07 00:48

Hier [http://www.rhizohm.net//irhetoric/blog/21/default.aspx] gibt es noch ein WPF-Beispiel, UIElement3D darf natürlich auch nicht fehlen :D .