Reputation: 5886
This is a follow-up to my question here.
I want to load the same assembly in different versions and create multiple instances of types from these assemblies.
Here is what I have:
I have an assembly asm.dll whos version (within AssemblyInfo.cs) is set to 1.0.0.0.
Then, I modify some code and increment the version to 2.0.0.0 and build it again as asm.dll.
Now, I have dir1/asm.dll and dir2/asm.dll.
Here is what I do:
assembly = Assembly.LoadFile(assemblyFile);
var types = assembly.GetTypes();
Type type = types.First<Type>(t => t.Name.Equals(backboneMemberClass + "Editor"));
MyObject myObject = (MyObject)assembly.CreateInstance("theClassIWantToInstantiate", false, BindingFlags.CreateInstance, null, new object[] { }, null, null);
Here is the problem:
The above works fine if I use "dir1/asm.dll" as assemblyFile: The call to assembly.CreateInstance(...)
returns me the requested instance.
If I use it again wit "dir2/asm.dll" it still works fine. Assembly.CreateInstance
returns the correct instance.
BUT, if I then again want to create an instance of an object I did already create before (through calling Assembly.CreateInstance
) I am getting the following Exception(s):
A first chance exception of type 'System.Exception' occurred in PresentationFramework.dll
A first chance exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll
The class I am loading is a .xaml WPF UserControl and the Stacktrace of the Exception says that the InitializeComponent() within the .xaml.cs file is throwing the Exception because it cannot find the .baml file.
Upvotes: 1
Views: 665
Reputation: 5886
After a week suffering and laboring with this issue, I finally found both the reason for the problem and its solution.
The problem lies within the auto-generated *.g.i.cs
file, which is called by the InitializeComponent()
method of a UserControl
, as seen by the following:
This file generates a string (a Resource Locator) that expresses the path to that xaml-component, as seen by the following:
Now, if you have multiple versions of the same assembly and both versions include the same xaml-file, WPF does not know what xaml-file to instantiate, because the Resource Locator only references the name of the assembly but not its version.
This results in a TargetInvocationException
, saying that
{"The component 'MyNamespace.MyUserControl' does not have a resource identified by the URI '/MyAssembly;comoponent/myusercontrol.xaml'"}
as follows:
The simple (but most definitely not obvious) solution for this is to add the version of the assembly to this Resource Locator. This can be achieved by modifying the build-file of the project by adding the <AssemblyVersion>
-tag as follows:
Credits for this go to:
Upvotes: 1