Загрузка DLL во время выполнения в C#
Я пытаюсь выяснить, как вы могли бы пойти об импорте и использовании .dll во время выполнения внутри приложения C#. Использование Сборки.LoadFile () мне удалось заставить мою программу загрузить dll (эта часть определенно работает, поскольку я могу получить имя класса с помощью ToString ()), однако я не могу использовать метод "Output" из моего консольного приложения. Я компилирую .затем dll перемещает его в проект моей консоли. Есть ли дополнительный шаг между CreateInstance и затем будучи в состоянии использовать методы?
это класс В моей DLL:
namespace DLL
{
using System;
public class Class1
{
public void Output(string s)
{
Console.WriteLine(s);
}
}
}
и вот приложение, которое я хочу загрузить DLL
namespace ConsoleApplication1
{
using System;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
var DLL = Assembly.LoadFile(@"C:visual studio 2012ProjectsConsoleApplication1ConsoleApplication1DLL.dll");
foreach(Type type in DLL.GetExportedTypes())
{
var c = Activator.CreateInstance(type);
c.Output(@"Hello");
}
Console.ReadLine();
}
}
}
5 ответов:
члены должны быть разрешимы во время компиляции для вызова непосредственно из C#. В противном случае необходимо использовать отражение или динамические объекты.
отражение
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(); } } }динамический (.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(); } } }
прямо сейчас, вы создаете экземпляр каждый тип, определенный в сборке. Вам нужно только создать один экземпляр
Class1для вызова метода: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(); } }
вам нужно создать экземпляр типа, который предоставляет
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()возвращает объект, который не имеет метода вывода.похоже, что вы пришли из динамических языков программирования? C# - это определенно не то, что вы пытаетесь сделать будет сложно.
поскольку вы загружаете определенную dll из определенного места, возможно, вы просто хотите добавить ее в качестве ссылки на свое консольное приложение?
если вы хотите загрузить сборку через
Assembly.Load, вам придется пройти через отражение, чтобы позвонить любые члены наcчто-то вроде
type.GetMethod("Output").Invoke(c, null);должны сделать это.
Это не так сложно.
вы можете проверить доступные функции загруженного объекта, и если вы найдете тот, который вы ищете по имени, а затем snoop его ожидаемые Пармы, если таковые имеются. Если это вызов, который вы пытаетесь найти,то вызовите его с помощью метода Invoke объекта MethodInfo.
другой вариант-просто построить внешние объекты в интерфейс и привести загруженный объект к этому интерфейсу. В случае успеха вызовите функцию в собственном коде.
Это довольно простой материал.
Comments