我可以将合同留在我与非代码合同开发人员使用的代码库合并的代码中吗?

时间:2014-09-02 15:48:33

标签: c# .net-4.5 development-environment code-contracts

在过去的几个月里,我一直在为我的公司开发一个辅助项目,但是现在已经决定它们更适合现有的产品。

我一直在使用微软的代码合同进行静态类型检查(部分原因是我之前没有使用它们,并且渴望学习)。

我的问题是,如果我将代码签入到代码库并且具有合同,那么每个其他开发人员是否需要安装代码合同工具才能继续开发?我知道有一个事实,他们都没有安装它,而且我是初中的所以我怀疑我能说服他们所有人接受它。

我正在使用.Net 4.5,因此包含了代码契约库,但我想知道Visual Studio是否会抱怨他们每次去的时候都没有使用构建选项中指定的CONTRACTS_FULL构建构建,或者,如果我在构建选项中留下CONTRACTS_FULL,当另一个开发人员尝试构建时会发生什么?此外,我想知道最终产品在合同失败时如何行动,但代码尚未使用代码合同重写器构建。

我只用一个项目创建了一个新的解决方案。创建了一个简单的函数,它触发了代码合同违规,卸载了代码契约并且未指定CONTRACTS_FULL。构建并运行它并收到以下错误:

Run-time exception (line 8): An assembly (probably "hdxticim") must be rewritten using the code contracts binary rewriter (CCRewrite) because it is calling Contract.Requires<TException> and the CONTRACTS_FULL symbol is defined.  Remove any explicit definitions of the CONTRACTS_FULL symbol from your project and rebuild.  CCRewrite can be downloaded from http://go.microsoft.com/fwlink/?LinkID=169180. 
After the rewriter is installed, it can be enabled in Visual Studio from the project's Properties page on the Code Contracts pane.  Ensure that "Perform Runtime Contract Checking" is enabled, which will define CONTRACTS_FULL

我认为错误消息需要重写,因为绝对没有指定CONTRACTS_FULL。

感谢MatíasFidemraizer,我们已经知道在使用Contract.Requires<TException>()而不是Contract.Requires()时会发生这种情况。

理想情况下,我想修改此行为,以便合同触发提供的异常,就好像它是一个普通的保护声明,而不是抱怨重写器。

Here's a fiddle证明了问题:https://dotnetfiddle.net/cxrAPe

3 个答案:

答案 0 :(得分:4)

不幸的是,如果没有强迫你的同事保持他们的个人环境,很难保持未通过nuget安装的库。代码合同似乎没有正式的Microsoft祝福包。

下面的四个午夜的帖子最近更新了我上面原先关注的答案,但我认为下半部分现在仍然相关。获得您的支持,人们!

在我的(公认的主观)体验中,如果事先没有在同事之间建立买入,那么这样的工具就会受到谴责。您可以尝试慢慢拉开主题,看看他们是否愿意使用它。

答案 1 :(得分:4)

简短的回答是:是的。如果您使用代码约定签入代码,那么可能构建该代码的所有开发人员也必须安装代码合同才能构建代码。

与@CBauer在他的回答中所写的相反,有一个&#34;祝福&#34;代码合约包。不,它不是NuGet包 - 它是基于MSI安装程序的安装。

最后,如果您处于调试版本的持续集成环境(例如,开发,QA / QC和/或测试),那么这些构建服务器也需要安装代码合同。

使用代码约定时,调试版本始终需要使用代码约定。请注意,发布版本的情况不一定。这取决于您使用的合同检查形式以及项目属性中指定的选项。

Code Contracts manual包含所有细节。它非常好,我强烈建议花时间阅读和理解它。

应该注意的是,如果您使用Contract.Requires<TException>(bool condition)形式的前提条件,则必须发布版本启用代码合同(请参阅部分5:使用指南,特别是第20页用法2 方案。)

由于您要将此代码集成到尚未使用代码合同开发的现有代码库中,因此您应考虑修改代码合同项目属性设置以符合上列出的使用方案3 “守则合同”手册第20页,并使用&#34;遗产&#34;重新制定合同。 if-then-throw模式。这将使您的团队能够最好地将代码库转移到各处使用代码合同,从而最终取代&#34; legacy&#34; if-then-throw先决条件检查与实际的代码合同Contract.Requires(bool condition)检查,如果您愿意,Contract.Requires<TException>(bool condition)检查。

更新:将很快成为代码合同的NuGet包 我今天在代码合同的新GitHub存储库中。对于那些不了解的人,微软已开源,现在是社区驱动的。

他们最近(早在1月份)宣布 v1.10.xxxx.RC1 发布。您可以找到有关它的信息here on their GitHub repository

答案 2 :(得分:0)

如果未安装代码合同重写器,

Contract.Requires<TException>()将失败,无论是否设置CONTRACTS_FULL

一种解决方案是构建一个单独的类FailableContract,用于测试由代码约定设置的预处理器条件CONTRACTS_FULL

然后,您需要做的就是在将代码提交到代码库之前,记住从构建参数中删除CONTRACTS_FULL。您仍然可以获得代码合同,其他人都可以获得保护声明。

FailableContract的一小部分(我还在写):

public class FailableContract
{

    public static void Requires(bool condition)
    {
        #if CONTRACTS_FULL
            Contract.Requires(condition);
        #else
            if (!condition) throw new ArgumentException(); //Just go with an argument exception because we haven't been supplied with an exception type.
        #endif
    }

    public static void Requires<TException>(bool condition) where TException : Exception, new()
    {
        #if CONTRACTS_FULL
            Contract.Requires<TException>(condition);
        #else
            if (!condition) throw new TException();
        #endif
    }
}

然后,一个简单的查找,将Contract.替换为FailableContract.应该会解决大多数问题。