我在VS2013中有一个C#解决方案,并安装了Code Contracts扩展。在我的解决方案中,我有一个应用程序项目(ProjectA)和一个类库项目(ProjectB)。 ProjectA引用ProjectB,并且ProjectB的大多数公共成员都有与之关联的合同。
我可以毫无问题地从ProjectA访问ProjectB的大多数成员,但在一个属性上我得到FileNotFoundException
,消息"无法加载文件或程序集& #39; ProjectB.Contracts,Version = ....'或其中一个依赖项。"
以下是融合日志所说的内容:
===预绑定状态信息===
日志:DisplayName = [SolutionName] .ProjectB.Contracts,Version = 1.0.5953.23121,Culture = neutral,PublicKeyToken = null(完全指定)
日志:Appbase = [SolutionDir] / [SolutionName] .ProjectA / bin / Debug /
日志:初始PrivatePath = NULL调用程序集:[SolutionName] .ProjectC,Version = 1.0.5953.23122,Culture = neutral,PublicKeyToken = null。
XXX
日志:此绑定在默认加载上下文中启动。
日志:使用应用程序配置文件:[MyDocuments] [SolutionName] [SolutionName] .ProjectA \ bin \ Debug [SolutionName] .ProjectA.vshost.exe.config
日志:使用主机配置文件:
日志:使用C:\ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ config \ machine.config中的计算机配置文件。
日志:此时策略未应用于引用(私有,自定义,部分或基于位置的程序集绑定)。
日志:尝试下载新网址 [SolutionDir] / [解决方案名称] .ProjectA / bin中/调试/ [解决方案名称] .ProjectB.Contracts.DLL。
日志:尝试下载新网址 [SolutionDir] / [解决方案名称] .ProjectA / bin中/调试/ [解决方案名称] .ProjectB.Contracts / [解决方案名称] .ProjectB.Contracts.DLL。
日志:尝试下载新网址 [SolutionDir] / [解决方案名称] .ProjectA / bin中/调试/ [解决方案名称] .ProjectB.Contracts.EXE。
日志:尝试下载新网址 [SolutionDir] / [解决方案名称] .ProjectA / bin中/调试/ [解决方案名称] .ProjectB.Contracts / [解决方案名称] .ProjectB.Contracts.EXE。
此解决方案中唯一的引用是标准Framework库,此解决方案中的其他项目以及另一个第一方库(仅引用System.dll)。我已尝试清理和重建此解决方案中的所有项目,以及其他第一方库。
我很困惑,原因有几个。
有谁知道这里会发生什么?
编辑:解决方案中的所有项目都面向.NET 4.0和#34;任何CPU"。
答案 0 :(得分:1)
以下是我试过的一些不起作用的事情:
在ProjectA的项目设置上,在Code Contracts选项卡上,我尝试将 ... ProjectB \ bin \ Debug \ CodeContracts 添加到字段额外合同库路径 。这并没有改变任何事情。
我还尝试手动添加对ProjectB.Contacts.dll的引用。这会将我的[]
变为FileNotFoundException
。这让我觉得这个问题可能是由于代码合同重写者的错误造成的。输入ILSpy。
导致此问题的合同基本上是原始源代码:
MissingMethodException
但是我把它放在这样的合同缩写方法中:
Contract.Requires<ArgumentNullException>(collection.All(x => x != null));
并在类似这样的类中调用它:
public static class PreCondition {
[ContractAbbreviator]
public static void NotIsOrHasNull<T>(IEnumerable<T> collection){
Contract.Requires<ArgumentNullException(collection != null,
"Collection cannot be null.");
Contract.Requires<ArgumentNullException>(collection.All(x => x != null),
"Collection cannot contain null.");
}
}
在ILSpy中查看麻烦的方法调用时,我看到它试图调用名为public class Class1{
public void DoStuff(IEnumerable<T> collection){
PreCondition.NotIsOrHasNull(collection);
foreach (var x in collection){
//Stuff
}
}
}
的实例方法,而不是静态方法Class1.NotIsOrHasNull
。
解决方案:
我更改了PreCondition.NotIsOrHasNull
类,将LINQ表达式移动到自己的PreCondition
函数中,并更改了合约缩写器以调用该方法。
Pure
现在,public static class PreCondition {
[Pure]
public static Boolean CollectionContainsNull(IEnumerable<T> collection){
Contract.Requires<ArgumentNullException(collection != null);
if (typeof(T).IsValueType)
return false;
return collection.Any(x => Object.Equals(x, null));
}
[ContractAbbreviator]
public static void NotIsOrHasNull<T>(IEnumerable<T> collection){
Contract.Requires<ArgumentNullException(collection != null,
"Collection cannot be null.");
Contract.Requires<ArgumentNullException>(!CollectionContainsNull(collection)),
"Collection cannot contain null.");
}
}
中的方法调用正常,IL在ILSpy中看起来是正确的。
+1到ILSpy!