Можно ли использовать dll-файлы в качестве модулей plug and play [duplicate]

Я думаю, что реальная (историческая) причина заголовочных файлов делала так же проще для разработчиков компилятора ... но тогда заголовочные файлы действительно дают преимущества. Проверьте этот предыдущий пост для дальнейших обсуждений ...

161
задан Anthony Mastrean 28 July 2011 в 17:11
поделиться

13 ответов

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

  с помощью System.Reflection;  Сборка MyDALL = Assembly.Load ("DALL");  // DALL имя вашей сборки Тип MyLoadClass = MyDALL.GetType ("DALL.LoadClass");  // имя вашего объекта класса obj = Activator.CreateInstance (MyLoadClass);   
0
ответ дан 2 revs, 2 users 73% 16 August 2018 в 05:33
поделиться
[D1] ((ISomeInterface) Activator.CreateInstance (Assembly.LoadFile ( "somePath") GetTypes () [0]).) SomeInterfaceMethod ().
2
ответ дан abatishchev 16 August 2018 в 05:33
поделиться

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

  // Предполагая, что moduleFileName содержит полный или действительный относительный путь к сборке var moduleInstance = Activator.CreateInstanceFrom (  moduleFileName, "MyNamespace.MyClass");  МетодInfo mi = moduleInstance.Unwrap (). GetType (). GetMethod («MyMethod»);  // Предполагая, что метод возвращает логическое значение и принимает один строковый параметр bool rc = Convert.ToBoolean (mi.Invoke (moduleInstance.Unwrap (), новый объект [] {"MyParamValue"}));   
2
ответ дан afiorillo 16 August 2018 в 05:33
поделиться

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

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

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

33
ответ дан Anthony Mastrean 16 August 2018 в 05:33
поделиться

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

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

1
ответ дан casperOne 16 August 2018 в 05:33
поделиться

Это легко.

Пример из MSDN:

  public static void Main () {// Использовать имя файла для загрузки сборки в текущее // приложение  домен.  Сборка a = Assembly.Load («пример»);  // Получить тип для использования.  Введите myType = a.GetType («Пример»);  // Получить метод для вызова.  MethodInfo myMethod = myType.GetMethod ("MethodA");  // Создаем экземпляр.  object obj = Activator.CreateInstance (myType);  // Выполнить метод.  myMethod.Invoke (obj, null);  }  

Вот ссылка:

https://msdn.microsoft.com/en-us/library/25y1ya39.aspx [ ! d5]

2
ответ дан Clearer 16 August 2018 в 05:33
поделиться
  • 1
    Это ужасный способ поддерживать динамическую загрузку кода. MS всегда любила заставлять нас вводить слишком много деталей. – Clearer 11 April 2018 в 07:43

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

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

2
ответ дан Dario Solera 16 August 2018 в 05:33
поделиться
  Монтажная сборка = Assembly.LoadFrom («MyAssembly.dll»);  Тип type = assembly.GetType («MyType»);  dynamic instanceOfMyType = Activator.CreateInstance (тип);   

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

1
ответ дан David Mkheyan 16 August 2018 в 05:33
поделиться
[D1] Да. У меня нет примеров, которые я сделал лично сейчас. Я отправлю позже, когда найду. В принципе, вы будете использовать отражение, чтобы загрузить сборку, а затем вытащить любые типы, которые вам нужны.

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

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

2
ответ дан Giovanni Galbo 16 August 2018 в 05:33
поделиться
[D5] Да. Вам нужно использовать Assembly.LoadFrom , чтобы загрузить сборку в память, затем вы можете использовать Activator.CreateInstance , чтобы создать экземпляр вашего предпочтительного типа. Сначала вам нужно посмотреть тип, используя отражение. Вот простой пример:

  Assembly assembly = Assembly.LoadFrom («MyNice.dll»);  Тип type = assembly.GetType («MyType»);  object instanceOfMyType = Activator.CreateInstance (type);   

Обновить

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

209
ответ дан Ian Kemp 16 August 2018 в 05:33
поделиться
  • 1
    У меня нет абсолютного пути к dll, к assembly.LoadFile и т. Д. не работают, какие-либо другие идеи? – MegaByte 22 January 2009 в 07:27
  • 2
    @MegaByte: LoadFrom отличается от LoadFile. Он разрешит ваши зависимости, и он должен разрешить имя DLL из известных путей (GAC, exe directory и т. Д.). См. MSDN для получения дополнительной информации. – Jeff Yates 18 January 2011 в 14:54
  • 3
    Это помогает ... отметить это как принятый ответ? – Cipi 14 February 2011 в 09:21
  • 4
    Еще одна вещь ... (я снова) Ум, вы не можете просто иметь «MyType». как имя типа, за ним следует NAMESPACE. Таким образом, это было бы более точным: Тип type = assembly.GetType («MyNamespace» + «.» + «MyType»); – Cipi 14 February 2011 в 10:46
  • 5
    @Cipi: Технически тип - это полное имя с именами (концепция пространства имен - это удобство для языка). У вас может быть тип без пространства имен внутри CLR - я просто предоставлял слишком упрощенный пример. – Jeff Yates 18 March 2011 в 19:35

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

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

   string assemblyName = "library.dll";  string assemblyPath = HttpContext.Current.Server.MapPath ("~ / bin /" + assemblyName);  Монтажная сборка = Assembly.LoadFrom (assemblyPath);  Тип 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.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
ответ дан Sofija 16 August 2018 в 05:33
поделиться

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

2
ответ дан Tim Cooper 16 August 2018 в 05:33
поделиться

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

  Объект IFace = (IFace) Activator.CreateInstance («AssemblyName», «TypeName») .Unwrap ();   

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

Пример:

  var aray = (IList) Активатор.  CreateInstance ( "mscorlib", "System.Collections.ArrayList") Развертка ().  aray.Add (10);  foreach (объект obj в aray) {Console.WriteLine (obj);  }  
16
ответ дан tvanfosson 16 August 2018 в 05:33
поделиться
  • 1
    Просто обратите внимание на это: ТипName должен быть полностью квалифицирован. Мне пришлось называть это так: Activator.CreateInstance («MyAssembly», «MyAssembly.TypeName») И это возвращает объект ObjectHandle . Чтобы перейти к вашему интерфейсу, вам нужно сделать ObjectHandle.UnWrap () – Anthony Sottile 8 August 2011 в 22:29
  • 2
    @ Энтони - я обновился. – tvanfosson 8 August 2011 в 22:56
Другие вопросы по тегам:

Похожие вопросы: