Einzelnen Beitrag anzeigen

Furtbichler
(Gast)

n/a Beiträge
 
#2

AW: MEF: Plugin-Schlittstelle in C#/WPF

  Alt 15. Okt 2013, 08:48
Geht es Dir um genau diese Lösung, oder irgend eine?

Dann versuch das hier:
1. Das Plugin-Interface IPlugin. Wird von jedem Plugin implementiert. Pro Assembly ein Plugin. Du kannst auch mehrere dort implementieren, aber dann funktioniert der Wrapper weiter unten nicht (kann aber erweitert werden).
Code:
public interface IPlugin
{
  string GetName();
  string GetDescription();
  string GetVersion();
  UserControl ConfigurationDialog();
  void Execute();
  ...
}
2. Der Plugin-Loader im Hauptprogramm. Sucht nach Assemblies und importiert die, die IPlugin implementieren.
Code:
var directoryInfo = new DirectoryInfo(path);
foreach (var file in directoryInfo.GetFiles("*.dll"))
{
   Wrapper pluginWrapper = new PluginWrapper(file.FullName);
   if (pluginWrapper.IsValid)
   {
     string fullname = pluginWrapper.Instance.GetName() + " " +
                   pluginWrapper.Instance.GetVersion();
      ...          
   }
}
Der Plugin-Wrapper:
Code:
internal class PluginWrapper
{
  private readonly IPlugin _pluginInstance;
  public bool IsValid;

  public PluginWrapper(string fullFilename)
  {
    IsValid = false;
    Assembly assembly = Assembly.LoadFile(fullFilename);
    var type = assembly.GetTypes().FirstOrDefault(IsPlugin);
    if (type == null)
      return;
   
    _pluginInstance = (IPlugin)Activator.CreateInstance(type);
    IsValid = true;
  }

  public IPlugin Instance { get { return _pluginInstance; } }

  private bool IsPlugin(Type type)
  {
    return type.IsClass && type.IsPublic && type.GetInterfaces().Contains(typeof(IPlugin));
  }
}
Ein Wrapper wird also mit dem vollständigen Pfadnamen der Assembly instantiiert. Der Wrapper prüft, ob eine IPlugin - Klasse in der Assembly vorhanden ist und setzt 'IsValid' auf true, wenn dem so ist. Dann ist über die Property 'Instance' auch eine Instanz der Implementierung abrufbar.

In dieser Implementierung wird nur die erste IPlugin-Klasse jeder Assembly geladen. Man kann das natürlich erweitern, sodaß alle Klassen geladen werden.

Wie Du siehst, habe ich keinerlei Attribute.

Ich muß aber ehrlich sagen, daß das so mit mein erstes C#-Projekt war, also kann man das bestimmt noch verbessern.
  Mit Zitat antworten Zitat