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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9650778/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 08:19:54  来源:igfitidea点击:

Prism assembly reference failure: System.Windows.Interactivity

c#.netwpfvisual-studioprism

提问by Ryan Norbauer

I have C#/WPF Prism (v4.0) app that has a persistent problem loading/resolving the System.Windows.Interactivity dll that comes with the Prism library. I've been working for three days straight trying to debug/solve this problem. I've learned a ton about .Net assembly resolution, but no luck so far on my problem, so I thought I'd turn to the StackOverflow community in a desperate plea for help. :)

我有 C#/WPF Prism (v4.0) 应用程序,该应用程序在加载/解决 Prism 库附带的 System.Windows.Interactivity dll 时一直存在问题。我已经连续工作三天试图调试/解决这个问题。我已经了解了很多关于 .Net 程序集分辨率的知识,但到目前为止我的问题还没有好运,所以我想我会在绝望的求助中求助于 StackOverflow 社区。:)

I have a module running as part of a larger Prism app, which needs to reference System.Windows.Interactivity in order to add behaviors. Thus I have a XAML user control specifying the namespace as follows:

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

And then I am trying to set a behavior on a child element of that UserControl as follows:

然后我尝试在该 UserControl 的子元素上设置行为,如下所示:

<ListBox Name="myListBox">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged">
            <i:InvokeCommandAction Command="{Binding SomeCommandOrOther}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</ListBox>

Oddly, the project builds fine, and when typing in the associate code-behind file and I can even get Intellisense auto-completionfor objects in the System.Windows.Interactivity namespace.

奇怪的是,该项目构建良好,并且在输入关联的代码隐藏文件时,我什至可以获得System.Windows.Interactivity 命名空间中对象的智能感知自动完成

However, at runtime only, I get a XamlParseException on the above ListBox element.

但是,仅在运行时,我在上述 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. 

The InnerException is of the type System.IO.FileNotFoundException

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"

...which, as I have learned from reading about assembly resolutions, usually suggests a problem resolving a strongly-named assembly rather than merely an inability to find the dll on disk (as the exception type would suggest).

...正如我从阅读程序集解析中了解到的那样,这通常表明在解决强命名程序集时存在问题,而不仅仅是无法在磁盘上找到 dll(如异常类型所建议的那样)。

The Fusion log information is as follows, including warning about partial binding for the assembly in question:

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.

Interestingly, if I look at my built project using the IL disassembler (ildasm.exe), System.Windows.Interactivity is not listed in the manifest as one of the referenced assemblies, though the other referenced Prism dlls show up there just fine. For example:

有趣的是,如果我使用 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
}

This problem is similar to the one mentioned in this other StackOverflow question: Referencing the correct System.Windows.Interactivity dll from Prism application. However, I am following the prescribed solution mentioned there (i.e., using the Prism version of System.Windows.Interactivity), to no avail. Just for fun, I have also tried using the System.Windows.Interactivity dlls that come with both the Expression Blend 3 and 4 SDKs (separately of course), but no luck with those either.

此问题类似于另一个 StackOverflow 问题中提到的问题:从 Prism 应用程序引用正确的 System.Windows.Interactivity dll。但是,我正在遵循那里提到的规定解决方案(即,使用 System.Windows.Interactivity 的 Prism 版本),但无济于事。只是为了好玩,我还尝试使用 Expression Blend 3 和 4 SDK 附带的 System.Windows.Interactivity dll(当然是分开的),但也没有运气。

I'm not doing anything differently in how I've loaded the System.Windows.Interactivity dll from how I've loaded all the other dlls that come with the Prism library (they all reside in a /lib folder in my solution, and I've added them using the "Add reference" > "Browse" menu in Visual Studio 2010 and pointing to those dlls on disk sitting all together in one directory.)

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

Any leads on where to turn next would be most appreciated! Many thanks.

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

采纳答案by Ryan Norbauer

At last, I found the answer!

终于,我找到了答案!

When DLLs in Prism modules are referenced, the .NET assembly resolution mechanism looks for the referenced assemblies in the /bin folder of the hostingapplication (i.e., the one with the Shell and Bootstrapper) rather than in the module'sbin directory (assuming you have set up your modules as separate projects in the solution, as I have).

当引用 Prism 模块中的 DLL 时,.NET 程序集解析机制在宿主应用程序的 /bin 文件夹(即带有 Shell 和 Bootstrapper 的文件夹)而不是模块的bin 目录中查找引用的程序集(假设您有像我一样,在解决方案中将您的模块设置为单独的项目)。

By coincidence, my hosting application happened to reference all the other Prism DLLs, so when the modules referenced those, it just found them in the hosting application's bin directory. However, my hosting application never referenced System.Windows.Interactivity, so adding it just to my module meant there was no such DLL to be found in the hosting applications /bin directory. The DLL is in fact being copied to the /bin directory of the module, but some quirk of the way assembly resolution works with Prism applications means that the app never checks for assemblies in that folder.

巧合的是,我的托管应用程序碰巧引用了所有其他 Prism DLL,因此当模块引用这些 DLL 时,它只是在托管应用程序的 bin 目录中找到了它们。但是,我的托管应用程序从未引用 System.Windows.Interactivity,因此仅将其添加到我的模块意味着在托管应用程序 /bin 目录中找不到此类 DLL。DLL 实际上被复制到模块的 /bin 目录中,但是程序集解析与 Prism 应用程序一起工作的一些怪癖意味着该应用程序从不检查该文件夹中的程序集。

So, in short: referenced assemblies in Prism applications apparently need to reside in the /bin folder of the hosting application.

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

I'm going to look at some means of using configuration to make this work more cleanly and intelligently, but the core of the problem has at least been uncovered.

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