Могу ли я загрузить сборку .NET во время выполнения и создать экземпляр типа, зная только имя?

Возможно ли создать экземпляр объекта во время выполнения, если у меня есть только имя DLL и имя класса без добавления ссылки на сборку в проекте? Класс реализует интерфейс, поэтому, как только я создам экземпляр класса, я затем передам его в интерфейс.

Название сборки:

library.dll

Имя типа:

Company.Project.Classname


EDIT: У меня нет абсолютного пути к DLL, поэтому Assembly.LoadFile не будет работать. DLL может быть в корне приложения, system32 или даже загружена в GAC.

Ответ 1

Да. Вам нужно использовать Assembly.LoadFrom, чтобы загрузить сборку в память, затем вы можете использовать Activator.CreateInstance, чтобы создать экземпляр вашего предпочтительного типа. Сначала вам нужно посмотреть тип, используя отражение. Вот простой пример:

Assembly assembly = Assembly.LoadFrom("MyNice.dll");

Type type = assembly.GetType("MyType");

object instanceOfMyType = Activator.CreateInstance(type);

Update

Если у вас есть имя файла сборки и имя типа, вы можете использовать Activator.CreateInstance(assemblyName, typeName), чтобы спросить разрешение типа .NET, чтобы решить эту проблему в тип. Вы можете обернуть это с помощью try/catch, чтобы в случае сбоя вы могли выполнить поиск каталогов, где вы можете специально хранить дополнительные сборки, которые иначе не могли бы быть найдены. Это будет использовать предыдущий метод в этой точке.

Ответ 2

Рассмотрим ограничения различных методов Load*. Из MSDN docs...

LoadFile не загружает файлы в контекст LoadFrom, а не разрешает зависимости, используя путь загрузки, как это делает метод LoadFrom.

Более подробную информацию о контекстах загрузки можно найти в документах LoadFrom.

Ответ 3

Activator.CreateInstance должен работать.

IFace object = (IFace)Activator.CreateInstance( "AssemblyName",
                                                "TypeName" )
                               .Unwrap();

Примечание. Имя типа должно быть полностью квалифицированным.

Пример:

var aray = (IList)Activator.CreateInstance("mscorlib","System.Collections.ArrayList").Unwrap();
aray.Add(10);

foreach (object obj in aray)
{
    Console.WriteLine(obj);
}

Ответ 4

Я нашел этот вопрос, и некоторые ответы очень полезны, однако у меня были проблемы с путями, поэтому этот ответ будет охватывать загрузку библиотеки путем поиска пути каталога bin.

Первое решение:

string assemblyName = "library.dll";
string assemblyPath = HttpContext.Current.Server.MapPath("~/bin/" + assemblyName);
Assembly assembly = Assembly.LoadFrom(assemblyPath);
Type T = assembly.GetType("Company.Project.Classname");
Company.Project.Classname instance = (Company.Project.Classname) Activator.CreateInstance(T);

Второе решение

string assemblyName = "library.dll";
string assemblyPath = HttpContext.Current.Server.MapPath("~/bin/" + assemblyName);
Assembly assembly = Assembly.LoadFile(assemblyPath);
(Company.Project.Classname) instance = (Company.Project.Classname) assembly.CreateInstance("Company.Project.Classname");

Вы можете использовать тот же принцип для интерфейсов (вы бы создали класс, но листинг для интерфейса), например:

(Company.Project.Interfacename) instance = (Company.Project.Interfacename) assembly.CreateInstance("Company.Project.Classname");

Этот пример предназначен для веб-приложения, но аналогичный может быть использован для настольного приложения, только путь разрешен по-разному, например

Path.GetDirectoryName(Application.ExecutablePath)

Ответ 5

Да. У меня нет примеров, которые я сделал лично сейчас. Я отправлю позже, когда найду. В основном вы будете использовать отражение, чтобы загрузить сборку, а затем вытащить все, что вам нужно.

Тем временем, эта ссылка должна начать:

Использование отражения для загрузки неучтенных сборок во время выполнения

Ответ 6

((ISomeInterface)Activator.CreateInstance(Assembly.LoadFile("somePath").GetTypes()[0])).SomeInterfaceMethod();

Ответ 7

В зависимости от того, насколько характерна эта функциональность для вашего проекта, вы можете рассмотреть что-то вроде MEF, которое позаботится о загрузка и связывание компонентов для вас.

Ответ 8

Вы можете загрузить сборку, используя методы * Assembly.Load **. Используя Activator.CreateInstance, вы можете создавать новые экземпляры нужного типа. Имейте в виду, что вы должны использовать полное имя типа класса, который хотите загрузить (например, Namespace.SubNamespace.ClassName). Используя метод InvokeMember класса Type, вы можете вызывать методы типа.

Кроме того, учтите, что после загрузки сборку нельзя выгружать до тех пор, пока весь AppDomain не будет выгружен (это в основном утечка памяти).

Ответ 9

Начиная с Framework v4.5 вы можете использовать Activator.CreateInstanceFrom(), чтобы легко создавать классы в сборках. В следующем примере показано, как его использовать и как вызвать метод, передающий параметры и возвращающее значение.

    // Assuming moduleFileName contains full or valid relative path to assembly    
    var moduleInstance = Activator.CreateInstanceFrom(moduleFileName, "MyNamespace.MyClass");
    MethodInfo mi = moduleInstance.Unwrap().GetType().GetMethod("MyMethod");
    // Assuming the method returns a boolean and accepts a single string parameter
    bool rc = Convert.ToBoolean(mi.Invoke(moduleInstance.Unwrap(), new object[] { "MyParamValue" } ));

Ответ 10

Да, вы хотите использовать статический метод Load в классе Assembly, а затем вызвать, затем вызвать метод CreateInstance в экземпляре Assembly, возвращенный вам из вызова Load.

Кроме того, вы можете вызвать один из других статических методов, начиная с "Загрузить" в классе Assembly, в зависимости от ваших потребностей.

Ответ 11

Assembly assembly = Assembly.LoadFrom("MyAssembly.dll");

Type type = assembly.GetType("MyType");

dynamic instanceOfMyType = Activator.CreateInstance(type);

Таким образом, вы можете использовать функции не с получением методаinfo, а затем вызывать его. Вы будете делать как этот экземплярOfMyType.MethodName(); Но вы не можете использовать Intellisense, потому что динамические типы вводятся во время выполнения, а не во время компиляции.

Ответ 12

Вы можете сделать следующее:

using System.Reflection;

Assembly MyDALL = Assembly.Load("DALL"); //DALL name of your assembly
Type MyLoadClass = MyDALL.GetType("DALL.LoadClass"); // name of your class
 object  obj = Activator.CreateInstance(MyLoadClass);

Ответ 13

Его Easy

Согласно MSDN

public static void Main()

    // Use the file name to load the assembly into the current
    // application domain.
    Assembly a = Assembly.Load("example");
    // Get the type to use.
    Type myType = a.GetType("Example");
    // Get the method to call.
    MethodInfo myMethod = myType.GetMethod("MethodA");
    // Create an instance.
    object obj = Activator.CreateInstance(myType);
    // Execute the method.
    myMethod.Invoke(obj, null);

Здесь ссылка для ссылки

https://msdn.microsoft.com/en-us/library/25y1ya39.aspx