Python для .NET: Как явно создавать экземпляры классов C #, используя разные версии одной и той же DLL?

У меня есть файл .cs вроде

namespace SomeNamepace
{


    public struct SomeStruct
    {
        ....
    }

    public static class SomeClass
    {
        ....
    }

Пока что я использую его с PythonNET, как

import clr
clr.AddReference('c:\\Test\Module.dll')
from SomeNamepace import SomeClass, SomeStruct

SomeClass.SomeMethod(...)

Моя проблема сейчас в том, что мне нужно работать с DLL с идентичные имена и номер версии не установлены, поэтому PythonNET не видеть их как два разных DLL, но как то же самое. Даже если я импортирую их, используя полный путь с AddReference.

Теперь я хотел бы использовать их явно, как указано здесь:

Python для .NET: использование того же .NET сборка в нескольких версиях

как

lib = clr.AddReference('c:\\Test\Module.dll')

Я много чего пытался создать экземпляр SomeClass like

lib.SomeNamespace.SomeClass()

или

import System
System.Activator.CreateInstance(lib.GetType('SomeNamespace.SomeClass'))

или используя методы Initialize или CreateInstance

или как указано в ссылке ниже

from System import Type
type1 = lib.GetType('SomeNamespace.SomeClass')
constructor1 = type1.GetConstructor(Type.EmptyTypes)    

В конце концов, все не удалось, что-то не найдено, нет метода и т. д. и т. д.

Какой будет правильный синтаксис для этого?

7 голосов | спросил Joe 20 PMpFri, 20 Apr 2018 16:13:20 +030013Friday 2018, 16:13:20

1 ответ


0

Я нашел старый список рассылки , который может объясни это

  

Все становится намного сложнее, если вам нужно загрузить более одного   версия конкретной сборки (или, скорее всего, у вас есть   зависимость от какой-то библиотеки делает это).

     

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

Размещенное там решение больше не работает, полагаю, что функция .NET устарела. Но есть решение для этого. Вместо использования PythonNet вы должны использовать .NET Framework напрямую:

import System

dll_ref = System.Reflection.Assembly.LoadFile(fullPath)
print(dll_ref.FullName)
print(dll_ref.Location)

Убедитесь, что используется правильная DLL.

Чтобы использовать несколько библиотек DLL с одной и той же версией, просто загрузите ее в другую переменную

another_dll_ref = System.Reflection.Assembly.LoadFile(anotherFullPath)

Теперь вы можете использовать объекты из указанной библиотеки DLL.

Экземпляр общедоступного нестатического класса

some_class_type = dll_ref.GetType('MyNamespace.SomeClass')
my_instance = System.Activator.CreateInstance(some_class_type)
my_instance.a = 4 # setting attribute
my_instance.b('whatever') # calling methods

Вызов метода в общедоступном статическом классе

some_class_type = dll_ref.GetType('MyNamespace.SomeClass')
method = some_class_type.GetMethod('SomeMethod')
# return type and list of parameters
method.Invoke(None, [1, 2.0, '3']) 

Создание экземпляра структуры

some_struct_type = dll_ref.GetType('MyNamespace.SomeStruct')
my_struct = System.Activator.CreateInstance(some_struct_type)
my_struct.a = 3

Из документов на LoadFile

  

Используйте метод LoadFile для загрузки и проверки сборок, которые имеют   идентичны, но расположены по разным путям.   загружать файлы в контекст загрузки и не разрешает   зависимости с использованием пути загрузки, как это делает метод LoadFrom.LoadFile   полезно в этом ограниченном сценарии, потому что LoadFrom не может быть использован для   загружать сборки, которые имеют одинаковые идентификаторы, но разные пути; Это   загрузит только первую такую ​​сборку.

Методы, которые не работают:

  • добавление ссылок на другие библиотеки DLL с разными версиями с использованием dll_ref = clr.AddReference(f) не работает, даже если имя файла указано явно и dll_ref и Reflection используются для получения методов

  • с использованием длинного имени (например, 'MyNamespace, Version=1.0.0.1, Culture=neutral, PublicKeyToken=null' с System.Reflection.Assembly.Load с версией будет по-прежнему использовать первую версию

  • System.Reflection.Assembly.LoadFrom не работает с несколькими версиями одной и той же DLL, если уже загружена сборка с таким же идентификатором. LoadFrom возвращает загруженную сборку, даже если указан другой путь. ( Doc LoadFrom )

ответил Joe 24 PMpTue, 24 Apr 2018 16:36:49 +030036Tuesday 2018, 16:36:49

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

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132