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。这是一个好方法吗?
答案 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(或您自己的例外)。
我是代码合约,但宁愿看到合约更详细。你一定要尝试做不变的工作。另一种方法是在您的界面上定义合同。