marc wellman
marc wellman

Reputation: 5886

Loading same Assembly with different versions and instnatiating multiple .xaml instances

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

Answers (1)

marc wellman
marc wellman

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:

enter image description here

This file generates a string (a Resource Locator) that expresses the path to that xaml-component, as seen by the following:

enter image description here

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:

enter image description here

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:

enter image description here

Credits for this go to:

Upvotes: 1

Related Questions