开发者

Need a suggestion with CodeContracts

开发者 https://www.devze.com 2023-01-28 01:40 出处:网络
Hi guys I\'m new to CC and I need your suggestion. I started with CC in my last project. I have a WCF contract, which should be implemented by third parties. I want to assign code contracts to service

Hi guys I'm new to CC and I need your suggestion. I started with CC in my last project. I have a WCF contract, which should be implemented by third parties. I want to assign code contracts to service contracts. Let's say I have a class Car (Service Contract) and it's OperationContract ICar. ICar has a method GetCar() which as I said above, should be implemented by our clients. I create a code Contract class for Icar and in GetCar method, I validate the contract using CarContractHelper class. I introduced a helper class which validates the Car class the following way: Contract.Ensure(CarContractHelper.Validate(Contract.Result<Car>())). Is this a correct approach to solve the problem? Or is there any better way? I'm also validating each property member of Car class in it's setters, what do you think about this, is it necessary or it's an overkill? Thanks And of course, I will mark the correct answer and vote up :)

UPDATE


@StriplingWarrior I introduced th开发者_JS百科e car validation helper to deal with the repetitive contract validation code. for example:

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

etc. Instead of writing everywhere Contract.Requires code, I just have one helper class for each business object which validates the business object's contract. And that's what I want to know, if this is a correct approach or maybe there is a better way? thanks.

P.S. I'm validating every property in their own setters because invariant method won't work for me (?), as far as I know, invariants works when any method of the class is called, and in my case, wcf contract doesn't have any methods. So I choose to validate inside properties setter. Is it a good approach?


I haven't done much with Code Contracts, but here are some observations:

One of the advantages of code contracts is the ability to look at the contract for a particular method and know what's expected. Seeing CarContractHelper.Validate(Contract.Result<Car>()) doesn't really tell me anything, so I would have to drill down to know that (for example) the return value's CarId is greater than zero. So in one way I would rather see Contract.Ensure(Contract.Result<Car>().CarId > 0), and maybe a few other requirements. On the other hand, I can see how this could create a lot of repetitive contract code that would be hard to manage if (for instance) you added a new property to the Car class.

Another potential advantage of code contracts is the ability to have compile-time checks on your requirements. For example, consider the following code:

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

If TestCar's contract requires that car.CarId > 0, and GetCar() failed to ensure that this was the case, the compiler can warn you about this fact. In order for this to work with a validation helper class I imagine that you'll need to make sure your validation helper class also uses code contract methods to do your contract checks.

Even though you are performing checks on the Car class's property setters, I do think it still makes sense to validate that all required values have been set before this method returns.


Altough Code Contracts can be used for this, I personally would not use it this way. I think pure validation belongs to the Domain Layer ( provided you're using a somewhat Domain Driven approach) , and the car should be able to be validated with or without Code Contracts.

In my opinion, it would be better if your API handled the invalid car or threw an appropriate exception. If you're using Code Contracts to check the car's validity, you only have 2 options: 1. Car is valid 2. Car is invalid, ContractException ( or your own exception).

I'm pro-Code Contracts, but would rather see the Contracts more verbose. You should definitely try to make the invariant work. An alternative is to define Contracts on your interface.

0

精彩评论

暂无评论...
验证码 换一张
取 消