2010-12-03 4 views
1

Salut les gars Je suis nouveau à CC et j'ai besoin de votre suggestion. J'ai commencé avec CC dans mon dernier projet. J'ai un contrat WCF, qui devrait être mis en œuvre par des tiers. Je souhaite attribuer des contrats de code aux contrats de service. Disons que j'ai une voiture de classe (contrat de service) et c'est OperationContract ICar. ICar a une méthode GetCar() qui, comme je l'ai dit plus haut, devrait être implémentée par nos clients. Je crée une classe de contrat de code pour Icar et dans la méthode GetCar, je valide le contrat en utilisant la classe CarContractHelper. J'ai introduit une classe d'aide qui valide la classe Car de la manière suivante: Contract.Ensure(CarContractHelper.Validate(Contract.Result<Car>())). Est-ce une approche correcte pour résoudre le problème? Ou y a-t-il un meilleur moyen? Je valide également chaque membre de la classe Car dans ses setters, que pensez-vous de cela, est-ce nécessaire ou c'est une surcharge? Merci Et bien sûr, je vais marquer la réponse correcte et vote perdu :)Besoin d'une suggestion avec CodeContracts

MISE À JOUR


@StriplingWarrior J'introduit l'assistant de validation de voiture pour traiter le code de validation de contrat répétitif. par exemple:

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

etc. Au lieu d'écrire partout code Contract.Requires, je viens d'une classe d'aide pour chaque objet métier qui valide le contrat de l'objet métier. Et c'est ce que je veux savoir, si c'est une approche correcte ou peut-être qu'il existe un meilleur moyen? merci.

P.S. Je valide toutes les propriétés dans leurs propres setters parce que la méthode invariante ne fonctionnera pas pour moi (?), Pour autant que je sache, invariants fonctionne quand n'importe quelle méthode de la classe est appelée, et dans mon cas, wcf contrat ne avoir des méthodes. Donc, je choisis de valider à l'intérieur des propriétés setter. Est-ce une bonne approche?

+0

Pouvez-vous fournir du code? On dirait que vous dites 'ICar.GetCar()' renvoie une valeur de type 'Car', mais dans ce cas, à quoi ressemble' Car'? Est-ce que 'Car' implémente' ICar'? – StriplingWarrior

+0

Orthographe ... 'Kilométrage'. –

+0

Merci Austin :-) Il est mis à jour – Davita

Répondre

1

Je ne l'ai pas fait beaucoup avec les contrats de code, mais voici quelques observations:

L'un des avantages des contrats de code est la possibilité de regarder le contrat pour une méthode particulière et de savoir ce qui est attendu. Voyant CarContractHelper.Validate(Contract.Result<Car>()) ne me dit vraiment rien, donc je devrais explorer en profondeur pour savoir que (par exemple) la valeur de retour CarId est supérieure à zéro. Donc, dans un sens, je préfère voir Contract.Ensure(Contract.Result<Car>().CarId > 0), et peut-être quelques autres exigences. D'autre part, je peux voir comment cela pourrait créer beaucoup de code de contrat répétitif qui serait difficile à gérer si (par exemple) vous avez ajouté une nouvelle propriété à la classe Car.

Un autre potentiel le potentiel des contrats de code est la possibilité d'avoir des vérifications à la compilation sur vos besoins. Par exemple, considérez le code suivant:

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

Si le contrat de TestCar exige que car.CarId > 0 et GetCar() n'a pas réussi à faire en sorte que ce fut le cas, le compilateur peut vous mettre en garde contre ce fait. Pour que cela fonctionne avec une classe d'aide de validation Je suppose que vous devez vous assurer que votre classe d'aide de validation également utilise des méthodes de contrat de code pour faire vos chèques de contrat.

Même si vous effectuez des contrôles sur les setters propriété de classe de voiture, je pense qu'il est toujours judicieux de vérifier que toutes les valeurs nécessaires ont été mises en avant cette méthode retourne.

+0

Maintenant, il est plus clair. Votez et j'ai mis à jour la question :) Merci pour votre soutien. – Davita

0

code Altough Les contrats peuvent être utilisés pour cela, personnellement, je ne l'utiliser de cette façon.Je pense que la validation pure appartient à la couche de domaine (à condition que vous utilisiez une approche plutôt axée sur le domaine), et la voiture devrait pouvoir être validée avec ou sans contrat de code. À mon avis, il serait préférable que votre API gère la voiture invalide ou jette une exception appropriée. Si vous utilisez des Contrats de Code pour vérifier la validité de la voiture, vous n'avez que 2 options: 1. La voiture est valide 2. La voiture est invalide, ContractException (ou votre propre exception).

Je suis pro-Code Contrats, mais préfère voir les contrats plus verbeux. Vous devriez certainement essayer de faire fonctionner l'invariant. Une alternative est de définir des contrats sur votre interface.

+0

Merci KoMet pour votre soutien. Peut-être avez-vous raison, mais je traite avec WCF DataContracts et ServiceContracts. ServiceContracts sont des interfaces, telles que GetCar() par exemple. Je ne peux pas avoir de couche de domaine jusqu'à cette interface, ça devrait être une interface. Et en ce qui concerne les contrats de données, sur le champ requis, CC lancera ArgumentException si le contrat est violé. Est-ce que je le fais de la mauvaise façon? Merci encore – Davita

+0

Je ne suis pas très familier avec WCF Data-and ServiceContracts, j'ai peur =) Vous n'avez pas tort de lancer une ArgumentException, je parlais simplement de la méthode de validation ne pas être très verbeux sur vos contrats, et pointant sur qu'il pourrait y avoir des scénarios où vous voulez plus de flexibilité que de lancer une argumentexception directement =) – koenmetsu