【wpf】[踩坑日记] “组件“XXX”不具有由 URI“XXX“识别的资源”
报错背景
这是一个和反射相关的奇怪问题:
具体报错如下:
报错的地方是:
这里是我想通过,prism提供的方式,弹出一个子窗口。这里prism应该也是用到的反射技术。
本来这段代码是正常工作的。
但是,在此段代码执行之前,我加了一段代码,也对这个界面的DLL进行了反射:
结果, prism就表示,找不到那个界面了。注释掉,这段反射,prism ShowDialog 又可以了。
感觉就是我对这个DLL反射之后,影响了prism的反射。
于是,我查找资料,发现有个博主和我遇到了类似的情况:
Wpf: “组件“XXX”不具有由 URI“XXX“识别的资源”的一个可能原因-IT Blog (itcn.blog)https://itcn.blog/p/18401329759.html
解决方案
解决方法,仅仅就是,将 LoadFile 改为 LoadFrom 即可!
LoadFile和LoadFrom
于是我去查了下 LoadFile 和 LoadFrom 有啥差异。他们之间主要有两个差异:
1 LoadFile()不会解析任何依赖
Assembly.LoadFile只载入相应的dll文件,比如Assembly.LoadFile("abc.dll"),则载入abc.dll,假如abc.dll中引用了def.dll的话,def.dll并不会被载入。
2 LoadFrom会解析依赖
Assembly.LoadFrom则不一样,它会载入dll文件及其引用的其他dll,比如上面的例子,def.dll也会被载入。
3 LoadFile()可以多次加载同一程序集
4 LoadFrom()不会重新进行加载已经加载过目标程序集
问题分析
应该是我使用了LoadFile() 相当于对dll,进行第二次的加载。第一次应该是prism进行加载的。我加载了之后,应该改变了什么,导致prism找不到之前加载的DLL了。
首先,要确定一下,prism是不是确实已经先加载过了:
我们可以在我们反射之前,通过调用函数,查看已经加载了哪些Assembly:
var aaa = AppDomain.CurrentDomain.GetAssemblies();
然后,打断点,发现确实已经有了:
如果再调用LoadFile,再次查看:
好家伙,aaa变量里 多了一个一模一样的Assembly。
反之,如果用LoadFrom确实就没有重复的加载。可能多了一个把prism搞懵逼了吧。
小结
那是不是LoadFrom就一定比LoadFile好用呢?(注意以下结论,我并未验证)
答:不一定。
首先LoadFrom效率上会更低。
其次同一台机器可能存在相同标识的多个程序集,而LoadFrom不会重复加载相同标识的程序集,这会导致,LoadFrom加载的不是你指定的程序集。解决方式一个取更特殊的名字,二是给程序集设置版本号,确保它的唯一性。
作者:宋桓公
出处:http://www.cnblogs.com/douzi2/
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。