Caricamento di DLL al runtime in C #

Sto cercando di capire come si può andare sull’importazione e l’uso di un file .dll in fase di esecuzione all’interno di un’applicazione C #. Usando Assembly.LoadFile () sono riuscito a far caricare il dll dal mio programma (questa parte è sicuramente funzionante dato che sono in grado di ottenere il nome della class con ToString ()), tuttavia non sono in grado di utilizzare l’output metodo dall’interno della mia applicazione console. Sto compilando il file .dll per poi spostarlo nel progetto della mia console. C’è un passaggio in più tra CreateInstance e quindi essere in grado di utilizzare i metodi?

Questa è la class nella mia DLL:

namespace DLL { using System; public class Class1 { public void Output(string s) { Console.WriteLine(s); } } } 

e qui è l’applicazione che voglio caricare la DLL

 namespace ConsoleApplication1 { using System; using System.Reflection; class Program { static void Main(string[] args) { var DLL = Assembly.LoadFile(@"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll"); foreach(Type type in DLL.GetExportedTypes()) { var c = Activator.CreateInstance(type); c.Output(@"Hello"); } Console.ReadLine(); } } } 

I membri devono essere risolvibili al momento della compilazione per essere richiamati direttamente da C #. Altrimenti è necessario utilizzare la riflessione o oggetti dinamici.

Riflessione

 namespace ConsoleApplication1 { using System; using System.Reflection; class Program { static void Main(string[] args) { var DLL = Assembly.LoadFile(@"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll"); foreach(Type type in DLL.GetExportedTypes()) { var c = Activator.CreateInstance(type); type.InvokeMember("Output", BindingFlags.InvokeMethod, null, c, new object[] {@"Hello"}); } Console.ReadLine(); } } } 

Dinamico (.NET 4.0)

 namespace ConsoleApplication1 { using System; using System.Reflection; class Program { static void Main(string[] args) { var DLL = Assembly.LoadFile(@"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll"); foreach(Type type in DLL.GetExportedTypes()) { dynamic c = Activator.CreateInstance(type); c.Output(@"Hello"); } Console.ReadLine(); } } } 

Al momento, stai creando un’istanza di ogni tipo definito nell’assembly . Devi solo creare una singola istanza di Class1 per chiamare il metodo:

 class Program { static void Main(string[] args) { var DLL = Assembly.LoadFile(@"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll"); var theType = DLL.GetType("DLL.Class1"); var c = Activator.CreateInstance(theType); var method = theType.GetMethod("Output"); method.Invoke(c, new object[]{@"Hello"}); Console.ReadLine(); } } 

Devi creare un’istanza del tipo che espone il metodo di Output :

 static void Main(string[] args) { var DLL = Assembly.LoadFile(@"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll"); var class1Type = DLL.GetType("DLL.Class1"); //Now you can use reflection or dynamic to call the method. I will show you the dynamic way dynamic c = Activator.CreateInstance(class1Type); c.Output(@"Hello"); Console.ReadLine(); } 

Activator.CreateInstance() restituisce un object, che non ha un metodo di output.

Sembra che tu venga da linguaggi di programmazione dinamici? C # non è sicuramente quello, e quello che stai cercando di fare sarà difficile.

Poiché stai caricando una dll specifica da una posizione specifica, potresti semplicemente aggiungerla come riferimento alla tua applicazione console?

Se si vuole assolutamente caricare l’assembly tramite Assembly.Load , si dovrà passare per riflessione per chiamare qualsiasi membro su c

Qualcosa come type.GetMethod("Output").Invoke(c, null); dovrebbe farlo

Non è così difficile.

È ansible controllare le funzioni disponibili dell’object caricato e, se si trova quello che si sta cercando per nome, quindi snoopare i suoi parmi previsti, se presenti. Se è la chiamata che stai cercando di trovare, chiamala usando il metodo Invoke dell’object MethodInfo.

Un’altra opzione è semplicemente creare oggetti esterni su un’interfaccia e lanciare l’object caricato su quell’interfaccia. In caso di successo, chiamare la funzione in modo nativo.

Questa è roba abbastanza semplice.