2017-06-01 9 views
0

Ich versuche, einen kleinen Plugin-Mechanismus durch eine DLL-Datei, die Bereitstellung meiner Klasse Plugin (Implementierung meiner Plugin -Interface unter dll und Hauptprojekt/Entschuldigung für die Nennung der beiden gleich) ein Attribut vom Typ bietet string und ein Hauptverfahren activate:Get Methoden und Attribute von Dll-Assembly

Schnittstelle:

public interface Plugin 
{ 
    string pluginName{get;set;} 
    void activate(System.Windows.Forms.Form main); 
} 

dll Klasse:

public class Plugin : WhiteA.Plugin 
     { 
      public string pluginName{get;set;} 

      public void activate(System.Windows.Forms.Form main){ 
       //find the right form to modify it 
       IEnumerable<System.Windows.Forms.ComboBox> ie= GetControlsOfType<System.Windows.Forms.ComboBox>(main); 
       System.Windows.Forms.ComboBox cb=GetControlsOfType<System.Windows.Forms.ComboBox>(main).FirstOrDefault(); 
       cb.Items.Add("Modification"); 
       System.Windows.Forms.MessageBox.Show(cb.SelectedItem.ToString()); 
      } 

      public static IEnumerable<T> GetControlsOfType<T>(System.Windows.Forms.Control root) 
       where T : System.Windows.Forms.Control 
      { 
       var t = root as T; 
       if (t != null) 
        yield return t; 

       var container = root as System.Windows.Forms.ContainerControl; 
       if (container != null) 
        foreach (System.Windows.Forms.Control c in container.Controls) 
         foreach (var i in GetControlsOfType<T>(c)) 
          yield return i; 
      } 
     } 

So kommt hier das Problem, es gibt keine type namens "Plugin" in der Baugruppe gefunden werden. Versucht, alle Typen von allen Assemblies im Verzeichnis zu holen, alle Methoden/Members/Custom Attribute von ihnen zu holen, sie zu protokollieren usw., aber es gibt nichts von meiner Klasse Plugin zu finden, während die DLL definitiv gefunden wird, so wie es ist gibt die MessageBox nicht zurück.

string[] files=new string[]{}; 
      string path="Error retrieving path"; 
      try{ 
       path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); 
       files = System.IO.Directory.GetFiles(path, "*.dll"); 
      }catch(Exception exF){ 

      } 
      if(files.Length>0){ 
       foreach (string dll in files){ 
        try{ 
         System.Reflection.Assembly sampleAssembly = System.Reflection.Assembly.LoadFrom(dll); 
         Type myType = sampleAssembly.GetType("Plugin"); 
         System.Reflection.MethodInfo method = myType.GetMethod("activate"); 
         object myInstance = Activator.CreateInstance(myType); 
         method.Invoke(myInstance, new object[]{this}); 
        }catch(Exception exL){ 

        } 
       } 
      }else{ 
       MessageBox.Show("No working plugins detected in " + path.ToString(), "Nothing to activate", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1); 
      } 

Ich weiß wohl meinen Code Sie wirklich chaotisch sieht alles - obwohl ich glaube, das letzte try -Block das einzige, was relevant ist hier, wollte sich in der Klasse setzen und die Schnittstelle für ein wenig Transparenz - und mein Englisch ist nicht perfekt, aber ich hoffe, jemand kann mir helfen, meine Attribut + Methode in der Versammlung zu finden.

EDIT:

    try{ 
         System.Reflection.Assembly sampleAssembly = System.Reflection.Assembly.LoadFrom(dll); 

         List<Type> list= sampleAssembly.GetTypes().Where(p => 
              p.Namespace == dll && 
              p.Name.Contains("Plugin") 
              ).ToList(); 
         Type myType=list.FirstOrDefault(); 

         //Type myType = sampleAssembly.GetType("Plugin"); 
         System.Reflection.MethodInfo method = myType.GetMethod("activate"); 
         object myInstance = Activator.CreateInstance(myType); 
         method.Invoke(myInstance, new object[]{this}); 

        } 

ich es änderte sich nach Getting all types in a namespace via reflection noch das gleiche Ergebnis, was habe ich falsch gemacht?

+0

Ich denke, dass Sie den Namespace an 'GetType()' übergeben müssen? wie zum Beispiel 'sampleAssembly.GetType (" MyApp.Plugins.Plugin ");'? Beachten Sie, dass Sie den _assembly_ Namen nicht übergeben sollten - siehe [die Dokumentation] (https://msdn.microsoft.com/en-us/library/y0cd10tb (v = vs.110) .aspx) – stuartd

+0

Dies wurde hier beantwortet . https://stackoverflow.com/questions/79693/getting-all-types-in-a-namespace-via-reflection/34869091#34869091 –

+0

@stuartd das würde bedeuten, dass alle meine Plugins den gleichen Namensraum haben müssen, richtig? Ist das notwendig/erlaubt? – Kartoffel

Antwort

0

Wie bereits von @stuartd aus:

Type myType = sampleAssembly.GetType("WhiteA_Plugin_PausedVideo.Plugin"); 

die Lösung, den Namespace verpasst

cb.Items.Add("Modification"); 

allerdings nicht funktioniert ... irgendwelche Vorschläge?

Zur Arbeit bekommen die Kinder des Formulars von Controls ["NameOfChild"] direkt, die Hilfe-Methode zum Abrufen aller Objekte nach Klasse scheint hier falsch zu sein.

Plugin funktioniert jetzt, danke!

Verwandte Themen