棱镜组件参考失败:System.Windows.Interactivity
Posted
技术标签:
【中文标题】棱镜组件参考失败:System.Windows.Interactivity【英文标题】:Prism assembly reference failure: System.Windows.Interactivity 【发布时间】:2012-03-27 21:22:56 【问题描述】:我的 C#/WPF Prism (v4.0) 应用程序在加载/解决 Prism 库附带的 System.Windows.Interactivity dll 时遇到问题。我已经连续工作了三天,试图调试/解决这个问题。我学到了很多关于 .Net 程序集解析的知识,但到目前为止我的问题还没有运气,所以我想我会求助于 *** 社区,绝望地寻求帮助。 :)
我有一个模块作为更大的 Prism 应用程序的一部分运行,它需要引用 System.Windows.Interactivity 才能添加行为。因此,我有一个 XAML 用户控件指定命名空间,如下所示:
<UserControl x:Class="MyApp.Modules.SourcesModule.myView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">
然后我尝试在该 UserControl 的子元素上设置行为,如下所示:
<ListBox Name="myListBox">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="Binding SomeCommandOrOther"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox>
奇怪的是,项目构建良好,并且在键入关联代码隐藏文件时,我什至可以为 System.Windows.Interactivity 命名空间中的对象获得 Intellisense 自动完成。
但是,仅在运行时,我在上面的 ListBox 元素上收到 XamlParseException。
Could not load file or assembly 'System.Windows.Interactivity, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
InnerException 的类型是 System.IO.FileNotFoundException
"Could not load file or assembly 'System.Windows.Interactivity, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.":"System.Windows.Interactivity, PublicKeyToken=31bf3856ad364e35"
...正如我从阅读有关程序集解决方案中了解到的那样,这通常表明解决强名称程序集的问题,而不仅仅是无法在磁盘上找到 dll(如异常类型所暗示的那样)。
Fusion 日志信息如下,包括对相关程序集的部分绑定的警告:
=== Pre-bind state information ===
LOG: User = aricebo-array\me
LOG: DisplayName = System.Windows.Interactivity, PublicKeyToken=31bf3856ad364e35
(Partial)
WRN: Partial binding information was supplied for an assembly:
WRN: Assembly Name: System.Windows.Interactivity, PublicKeyToken=31bf3856ad364e35 | Domain ID: 1
WRN: A partial bind occurs when only part of the assembly display name is provided.
WRN: This might result in the binder loading an incorrect assembly.
WRN: It is recommended to provide a fully specified textual identity for the assembly,
WRN: that consists of the simple name, version, culture, and public key token.
WRN: See whitepaper http://go.microsoft.com/fwlink/?LinkId=109270 for more information and common solutions to this issue.
LOG: Appbase = file:///C:/Users/me/Documents/Development Projects/Desktop apps/Prism/MyApp/Src/MyApp/bin/Debug/
LOG: Initial PrivatePath = NULL
Calling assembly : PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Users/me/Documents/Development Projects/Desktop apps/Prism/MyApp/Src/MyApp/bin/Debug/System.Windows.Interactivity.DLL.
LOG: Attempting download of new URL file:///C:/Users/me/Documents/Development Projects/Desktop apps/Prism/MyApp/Src/MyApp/bin/Debug/System.Windows.Interactivity/System.Windows.Interactivity.DLL.
LOG: Attempting download of new URL file:///C:/Users/me/Documents/Development Projects/Desktop apps/Prism/MyApp/Src/MyApp/bin/Debug/System.Windows.Interactivity.EXE.
LOG: Attempting download of new URL file:///C:/Users/me/Documents/Development Projects/Desktop apps/Prism/MyApp/Src/MyApp/bin/Debug/System.Windows.Interactivity/System.Windows.Interactivity.EXE.
有趣的是,如果我使用 IL 反汇编程序 (ildasm.exe) 查看构建的项目,System.Windows.Interactivity 并未作为引用的程序集之一列在清单中,尽管其他引用的 Prism dll 仅显示在那里美好的。例如:
.assembly extern Microsoft.Practices.Prism
.publickeytoken = (31 BF 38 56 AD 36 4E 35 ) // 1.8V.6N5
.ver 4:0:0:0
.assembly extern Microsoft.Practices.Unity
.publickeytoken = (31 BF 38 56 AD 36 4E 35 ) // 1.8V.6N5
.ver 2:0:414:0
这个问题类似于另一个 *** 问题中提到的问题:Referencing the correct System.Windows.Interactivity dll from Prism application。但是,我遵循那里提到的规定解决方案(即使用 System.Windows.Interactivity 的 Prism 版本),但无济于事。只是为了好玩,我还尝试使用 Expression Blend 3 和 4 SDK 附带的 System.Windows.Interactivity dll(当然是分开的),但也没有运气。
我加载 System.Windows.Interactivity dll 的方式与加载 Prism 库附带的所有其他 dll 的方式没有什么不同(它们都位于我的 /lib 文件夹中)解决方案,我已经使用 Visual Studio 2010 中的“添加引用”>“浏览”菜单添加了它们,并指向磁盘上的那些 dll,它们一起位于一个目录中。)
任何关于下一步转向的线索将不胜感激!非常感谢。
【问题讨论】:
GAC 中有版本吗?您是否正在构建“任何 CPU”并在开发时引用 64 位,但在运行时绑定 32 位? FWIW,我不知道。gacutil -l
确认没有在 GAC 中运行的 System.Windows.Interactivity 版本。为了回答您的问题,我在项目属性中使用“任何 CPU”作为平台目标进行构建。我的测试机/操作系统是 64 位的。但是,我知道的不够多,无法在运行时回答您关于 32 位绑定的问题。你能告诉我如何检查吗?谢谢!
尝试构建为 x86 看看会发生什么
@RitchMelton:这是一个很好的假设。唉,然而,我试了一下,当目标是 x86 或 x64 时,错误仍然存在。
【参考方案1】:
我终于找到了答案!
当 Prism 模块中的 DLL 被引用时,.NET 程序集解析机制会在 宿主 应用程序(即具有 Shell 和 Bootstrapper 的那个)的 /bin 文件夹中查找被引用的程序集,而不是比在 模块的 bin 目录中(假设您已将模块设置为解决方案中的单独项目,就像我一样)。
巧合的是,我的托管应用程序碰巧引用了所有其他 Prism DLL,因此当模块引用这些 DLL 时,它只是在托管应用程序的 bin 目录中找到它们。但是,我的托管应用程序从未引用 System.Windows.Interactivity,因此仅将它添加到我的模块意味着在托管应用程序 /bin 目录中找不到这样的 DLL。实际上,DLL 被复制到模块的 /bin 目录,但是程序集解析与 Prism 应用程序一起工作的方式的一些怪癖意味着该应用程序永远不会检查该文件夹中的程序集。
因此,简而言之:Prism 应用程序中引用的程序集显然需要驻留在托管应用程序的 /bin 文件夹中。
我将研究一些使用配置的方法来使这项工作更加干净和智能,但问题的核心至少已经被发现。
【讨论】:
this article 的“将模块添加到应用程序”部分提供了一些关于在 Prism 应用程序中管理程序集组合方式的见解和技巧(即模块化的怪癖)。 我使用了 Expression blend SDK 中的 dll 并将其移至 common Libs 文件夹。我的一个模块正在使用 dll,所以正如您提到的,添加对 Shell 应用程序的引用是有效的。以上是关于棱镜组件参考失败:System.Windows.Interactivity的主要内容,如果未能解决你的问题,请参考以下文章
约束上的唯一约束失败:棱镜中的`User_Account_userId_key`