我想创建名为view.xaml
的.xaml UserControl的多个实例,它位于程序集dir1\asm.dll
和dir2\asm.dll
中,而asm.dll
是相同的程序集,只有不同在其版本号和view.xaml的实现。
我有以下设置:
public void TestCreation() {
Assembly asm = null;
asm = Assembly.LoadFile("dir1\asm.dll");
CreateView(asm); // works!
asm = Assembly.LoadFile("dir2\asm.dll");
CreateView(asm); // works!
asm = Assembly.LoadFile("dir1\asm.dll");
CreateView(asm); // FAILS!
}
public void CreateView(Assembly assembly)
{
Type type = assembly.GetTypes().First<Type>(t => t.Name.Equals("View"));
UserControl view = (UserControl)assembly.CreateInstance(type.FullName, false, BindingFlags.CreateInstance, null, new object[] { }, null, null);
}
我收到以下例外:
带有异常详细信息
我能够在view.xaml的InitializeComponent()方法中跟踪到这个位置的问题:
,更具体地说,在InitializeComponent()中:
答案 0 :(得分:1)
嗯,这很有趣......
两个程序集都具有相同的资源Uri。如果Uri包含版本但是VS似乎没有把它放在那里它会工作。哪一个最后加载(asm1或asm2)似乎能够使用非版本化的Uri而不会崩溃。
如果,而不是: &#34; / ProblemEditor;组件/ problemeditor.xaml&#34;
你有:&#34; / ProblemEditor; v1.0.0.0; component / problemeditor.xaml&#34;和&#34; / ProblemEditor; v2.0.0.0; component / problemeditor.xaml&#34;
然后就不会有问题了。
我为重建您的环境所做的是:
然后我:
然后你的代码就可以了!作品! WORKS!
我希望这对你来说是一个可以接受的解决方案。如果有其他人在不破坏dll的情况下解决这个问题,我也有兴趣知道。
答案 1 :(得分:0)
经过一周的痛苦和苦苦挣扎,我终于找到了问题的原因及其解决方案。
问题在于自动生成的*.g.i.cs
文件,该文件由InitializeComponent()
的{{1}}方法调用,如下所示:
此文件生成一个字符串(资源定位器),表示该xaml组件的路径,如下所示:
现在,如果您有同一程序集的多个版本并且两个版本都包含相同的xaml文件,那么 WPF 不知道要实例化的xaml文件,因为资源定位器仅引用程序集的名称,但不引用其版本。
这导致UserControl
,说
{“组件'MyNamespace.MyUserControl'没有由URI标识的资源'/ MyAssembly; comoponent/myusercontrol.xaml'”}
如下:
这个简单(但绝不是很明显)的解决方案是将程序集的版本添加到此资源定位器。这可以通过添加TargetInvocationException
- 标记修改项目的构建文件来实现,如下所示:
对此的信誉转到: