这是我的问题here的后续内容。
我想在不同版本中加载相同的程序集,并从这些程序集中创建多个类型实例。
这就是我所拥有的:
我有一个程序集asm.dll,其版本(在AssemblyInfo.cs中)设置为1.0.0.0。
然后,我修改了一些代码并将版本增加到2.0.0.0并再次将其构建为asm.dll。
现在,我有dir1 / asm.dll和dir2 / asm.dll。
以下是我的工作:
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);
问题在于:
如果我使用“dir1 / asm.dll”作为assemblyFile,上面的工作正常:对assembly.CreateInstance(...)
的调用会返回我请求的实例。
如果我再次使用它“dir2 / asm.dll”它仍然可以正常工作。 Assembly.CreateInstance
返回正确的实例。
但是,如果我再次想要创建一个我之前已创建的对象的实例(通过调用Assembly.CreateInstance
),我将得到以下异常:
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
我正在加载的类是.xaml WPF UserControl,Exception的Stacktrace表示.xaml.cs文件中的InitializeComponent()抛出了Exception,因为它无法找到.baml文件。
答案 0 :(得分:1)
经过一周的痛苦和苦苦挣扎,我终于找到了问题的原因及其解决方案。
问题在于自动生成的*.g.i.cs
文件,该文件由InitializeComponent()
的{{1}}方法调用,如下所示:
此文件生成一个字符串(资源定位器),表示该xaml组件的路径,如下所示:
现在,如果您有同一程序集的多个版本并且两个版本都包含相同的xaml文件,那么 WPF 不知道要实例化的xaml文件,因为资源定位器仅引用程序集的名称,但不引用其版本。
这导致UserControl
,说
{&#34;组件&#39; MyNamespace.MyUserControl&#39;没有由URI&#39; / MyAssembly标识的资源; comoponent / myusercontrol.xaml&#39;&#34;}
如下:
这个简单(但绝不是很明显)的解决方案是将程序集的版本添加到此资源定位器。这可以通过添加TargetInvocationException
- 标记修改项目的构建文件来实现,如下所示:
对此的信誉转到: