Загрузка 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();
}
}
}
943   5  

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

    Ничего не найдено.