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

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

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

Library.dll

Имя типа:

Company.Project.Classname


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

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

 Assembly assembly = Assembly.LoadFrom("MyNice.dll"); Type type = assembly.GetType("MyType"); object instanceOfMyType = Activator.CreateInstance(type); 

Обновить

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

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

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

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

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); } 

Я нашел этот вопрос, и некоторые ответы очень полезны, однако у меня были проблемы с путями, поэтому этот ответ будет охватывать загрузку библиотеки путем поиска пути к каталогу 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"); 

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

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

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

 Path.GetDirectoryName(Application.ExecutablePath) 

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

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

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

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

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

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

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

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

  // 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" } )); 

Это просто.

Пример из 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

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

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

 Assembly assembly = Assembly.LoadFrom("MyAssembly.dll"); Type type = assembly.GetType("MyType"); dynamic instanceOfMyType = Activator.CreateInstance(type); 

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

Вы можете сделать так:

 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); 
  • Загрузка нескольких версий одной и той же сборки
  • Правильное изменение неопределенного поведения, если число больше ширины типа?
  • Почему XCHG reg, reg 3 инструкции по микрооперации на современных архитектурах Intel?
  • Как я могу просмотреть MSIL / CIL, сгенерированный компилятором C #? Почему это называется сборкой?
  • Код C ++ для проверки гипотезы Collatz быстрее, чем assembly вручную - почему?
  • _addcarry_u64 и _addcarryx_u64 с MSVC и ICC
  • Цикл с вызовом функции быстрее, чем пустой цикл
  • Visual Studio «Не удалось скопировать» ... во время сборки
  • Очень быстро memcpy для обработки изображений?
  • Почему mulss занимает всего 3 цикла на Хасуэлле, отличном от таблиц инструкций Агнера?
  • Как получить вывод ассемблера из источника C / C ++ в gcc?
  • Давайте будем гением компьютера.