Ich versuche herauszufinden, wie Sie zur Laufzeit eine DLL in eine C # -Anwendung importieren und verwenden können. Verwenden von Assembly.LoadFile () Ich habe es geschafft, dass mein Programm die DLL lädt (dieser Teil funktioniert definitiv, da ich den Namen der Klasse mit ToString () abrufen kann), kann jedoch die 'Ausgabe' nicht verwenden. Methode aus meiner Konsolenanwendung. Ich kompiliere die DLL und verschiebe sie dann in das Projekt meiner Konsole. Gibt es einen zusätzlichen Schritt zwischen CreateInstance und der Verwendung der Methoden?
Dies ist die Klasse in meiner DLL:
namespace DLL
{
using System;
public class Class1
{
public void Output(string s)
{
Console.WriteLine(s);
}
}
}
und hier ist die Anwendung, die ich die DLL laden möchte
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();
}
}
}
c#
reflection
dll
Danbroooks
quelle
quelle
Antworten:
Mitglieder müssen zur Kompilierungszeit auflösbar sein, damit sie direkt von C # aufgerufen werden können. Andernfalls müssen Sie Reflexions- oder dynamische Objekte verwenden.
Reflexion
Dynamisch (.NET 4.0)
quelle
Output
jeden Typ in der Assembly aufzurufen , der wahrscheinlich werfen wird, bevor die "richtige" Klasse gefunden wird ...IDog dog = someInstance as IDog;
testen, ob sie nicht null sind. Stellen Sie Ihre Schnittstellen in eine gemeinsame DLL, die von Clients gemeinsam genutzt wird, und jedes Plugin, das dynamisch geladen wird, muss diese Schnittstelle implementieren. Auf diese Weise können Sie Ihren Client anhand der IDog-Schnittstelle codieren und zur Kompilierungszeit eine Intellisense + Strong-Typprüfung durchführen, anstatt Dynamic zu verwenden.continue
so dass dies, wie @ReedCopsey sagte, nicht ausgelöst wird, bevor die Klasse gefunden wurde.Im Moment erstellen Sie eine Instanz für jeden in der Assembly definierten Typ . Sie müssen nur eine einzelne Instanz von erstellen
Class1
, um die Methode aufzurufen:quelle
Sie müssen eine Instanz des Typs erstellen, der die
Output
Methode verfügbar macht :quelle
Activator.CreateInstance()
Gibt ein Objekt zurück, das keine Ausgabemethode hat.Sie kommen aus dynamischen Programmiersprachen? C # ist definitiv nicht das, und was Sie versuchen zu tun, wird schwierig sein.
Da Sie eine bestimmte DLL von einem bestimmten Speicherort laden, möchten Sie sie möglicherweise nur als Referenz zu Ihrer Konsolenanwendung hinzufügen.
Wenn Sie die Assembly unbedingt über laden möchten
Assembly.Load
, müssen Sie über Reflection gehen, um Mitglieder anzurufenc
So etwas
type.GetMethod("Output").Invoke(c, null);
sollte es tun.quelle
Es ist nicht so schwierig.
Sie können die verfügbaren Funktionen des geladenen Objekts überprüfen. Wenn Sie das gesuchte Objekt anhand des Namens finden, können Sie gegebenenfalls die erwarteten Parameter überprüfen. Wenn es sich um den Aufruf handelt, den Sie suchen, rufen Sie ihn mit der Invoke-Methode des MethodInfo-Objekts auf.
Eine andere Möglichkeit besteht darin, Ihre externen Objekte einfach in eine Schnittstelle zu erstellen und das geladene Objekt in diese Schnittstelle umzuwandeln. Wenn erfolgreich, rufen Sie die Funktion nativ auf.
Das ist ziemlich einfaches Zeug.
quelle