3

My problem: I have an assembly in 2 versions and want to use them at the same time in my Python project.

The .NET libs are installed in GAC (MSIL), having the same public token:

lib.dll (1.0.0.0)
lib.dll (2.0.0.0)

In Python I want something like that:

import clr
clr.AddReference("lib, Version=1.0.0.0, ...")
from lib import Class
myClass1 = Class()
myClass1.Operation()

*magic*

clr.AddReference("lib, Version=2.0.0.0, ...")
from lib import class
myClass2 = Class()
myClass2.Operation()
myClass2.OperationFromVersion2()

*other stuff*

# both objects should be accessibly
myClass1.Operation() 
myClass2.OperationFromVersion2()

Is there a way to do that? Something with AppDomains or bindingRedirect?

Note: Of course myClass1.operationFromVersion2() can fail...

2
  • how would you add 2 versions of assemblies to references in .NET? Commented Sep 7, 2015 at 5:56
  • 1
    I can use reflections there. Commented Oct 6, 2015 at 9:22

2 Answers 2

4

Well I found a solution: Python for .NET also supports Reflection!

Instead of

clr.AddReference("lib, Version=1.0.0.0, ...")

You have to use

assembly1 = clr.AddReference("lib, Version=1.0.0.0, ...")

With that assembly you can use all the Reflection stuff like in C#. In my example I have to use following code (same for version 2):

from System import Type
type1 = assembly1.GetType(...)
constructor1 = type1.GetConstructor(Type.EmptyTypes)
myClass1 = constructor1.Invoke([])
Sign up to request clarification or add additional context in comments.

1 Comment

This is great answer and surely should be added to pythonnet documentation!
2

I could not get it working using the accepted answer. Here is my solution.

Instead of using PythonNet you must use the .NET framework directly:

import System

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

Check that the correct DLL is used.

To use multiple DLLs with the same version just load it to another variable

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

Now you can use objects from the specified dll.

Instance of a public non-static class

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

Calling a method in a public static class

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']) 

Creating a instance of a struct

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

(taken from my question Python for .NET: How to explicitly create instances of C# classes using different versions of the same DLL?)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.