需要CodeContracts的建议

时间:2010-12-03 20:12:40

标签: c# validation code-contracts

你好 我是CC的新手,我需要你的建议。我在上一个项目中开始使用CC。我有一份WCF合同,应该由第三方实施。我想将代码合同分配给服务合同。假设我有一个类Car(服务合同),它是OperationContract ICar。 ICar有一个方法GetCar(),正如我上面所说,应该由我们的客户实现。我为Icar创建了一个代码Contract类,在GetCar方法中,我使用CarContractHelper类来验证合同。我介绍了一个帮助器类,它通过以下方式验证Car类:Contract.Ensure(CarContractHelper.Validate(Contract.Result<Car>()))。这是解决问题的正确方法吗?还是有更好的方法吗? 我也在验证其中每个属于Car class的物业成员,您对此有何看法,是否有必要或者这是一种矫枉过正? 谢谢 当然,我会标记正确的答案并投票:)

更新


@StriplingWarrior我介绍了汽车验证帮助器来处理重复的合同验证代码。例如:

Contract.Requires(!string.IsNullOrWhiteSpace(car.Id);
Contract.Requires(car.Mileage > 0);

等。而不是在任何地方写Contract.Requires代码,我只为每个业务对象都有一个帮助程序类来验证业务对象的合同。这就是我想知道的,如果这是一种正确的方法,或者可能有更好的方法? 感谢。

P.S。我正在验证他们自己的setter中的每个属性因为invariant方法对我来说不起作用(?),据我所知,不变量在调用类的任何方法时都有效,而在我的情况下,wcf契约没有有什么方法。所以我选择验证内部属性setter。这是一个好方法吗?

2 个答案:

答案 0 :(得分:1)

我对代码合同做的不多,但这里有一些观察:

代码合同的一个优点是能够查看特定方法的合同并知道预期的内容。看到CarContractHelper.Validate(Contract.Result<Car>())并没有真正告诉我什么,所以我必须深入了解(例如)返回值的CarId大于零。所以在某种程度上我宁愿看Contract.Ensure(Contract.Result<Car>().CarId > 0),也许还有其他一些要求。另一方面,我可以看到,如果(例如)您向Car类添加了新属性,这可能会创建大量难以管理的重复合同代码。

代码合同的另一个潜在优势是能够对您的需求进行编译时检查。例如,请考虑以下代码:

var car = _carService.GetCar();
_crashTestUtil.TestCar(car);

如果TestCar的合同要求car.CarId > 0,并且GetCar()未能确保这种情况,则编译器可以警告您这一事实。为了使其与验证助手类一起工作,我想你需要确保你的验证助手类使用代码契约方法来进行合同检查。

即使您正在对Car类的属性设置器执行检查,我认为在此方法返回之前验证是否已设置所有必需值仍然有意义。

答案 1 :(得分:0)

Altough Code Contracts可用于此,我个人不会这样使用它。我认为纯验证属于域层(假设你使用的是一种有点域驱动的方法),并且汽车应该能够在有或没有代码约定的情况下进行验证。

在我看来,如果您的API处理了无效汽车或引发了适当的例外情况会更好。如果您使用代码合同来检查汽车的有效性,您只有2个选项:1。汽车有效2.汽车无效,ContractException(或您自己的例外)。

我是代码合约,但宁愿看到合约更详细。你一定要尝试做不变的工作。另一种方法是在您的界面上定义合同。