Prism程序集引用失败:System.Windows.Interactivity

本文关键字:System Windows Interactivity 失败 程序集 引用 Prism | 更新日期: 2023-09-27 18:27:18

我有一个C#/WPF Prism(v4.0)应用程序,它在加载/解决Prism库附带的System.Windows.Interactivity dll时出现持续问题。我已经连续工作了三天,试图调试/解决这个问题。我已经了解了很多关于.Net组装解决方案的知识,但到目前为止,我的问题还没有解决,所以我想我应该向StackOverflow社区绝望地寻求帮助。:)

我有一个模块作为一个更大的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
}

这个问题类似于另一个StackOverflow问题中提到的问题:从Prism应用程序引用正确的System.Windows.Interactivity dll。然而,我正在遵循上面提到的规定解决方案(即使用棱镜版本的System.Windows.Interactivey),但没有效果。为了好玩,我还尝试过使用Expression Blend 3和4 SDK附带的System.Windows.Interactivity dll(当然是单独的),但也没有成功。

我加载System.Windows.Interactivity dll的方式与加载Prism库附带的所有其他dll的方式没有任何不同(它们都位于我的解决方案中的/lib文件夹中,我使用Visual Studio 2010中的"添加引用">"浏览"菜单添加了它们,并指向磁盘上放在一个目录中的那些dll。)

任何关于下一步转向的线索都将不胜感激!非常感谢。

Prism程序集引用失败:System.Windows.Interactivity

终于找到了答案!

当Prism模块中的DLL被引用时,.NET程序集解析机制会在托管应用程序的/bin文件夹(即带有Shell和Bootstrapper的应用程序)中查找被引用的程序集,而不是在module的bin目录中(假设您已将模块设置为解决方案中的独立项目,就像我所做的那样)。

巧合的是,我的托管应用程序碰巧引用了所有其他Prism DLL,所以当模块引用这些DLL时,它只是在托管应用程序的bin目录中找到了它们。但是,我的宿主应用程序从未引用过System.Windows.Interactivity,因此仅将其添加到我的模块中意味着在宿主应用程序/bin目录中找不到这样的DLL。事实上,DLL正被复制到模块的/bin目录中,但Prism应用程序的程序集解析方式有些古怪,这意味着该应用程序永远不会检查该文件夹中的程序集。

简而言之:Prism应用程序中被引用的程序集显然需要驻留在宿主应用程序的/bin文件夹中。

我将研究一些使用配置使这项工作更加干净和智能的方法,但问题的核心至少已经被发现了。