33 votes

Mappage des attributs de validation de l'entité de domaine au DTO

J'ai une Couche Domaine de l'entité:

public class Product
{
    public int Id { get; set; }

    public string Name { get; set; }

    public decimal Price { get; set;}
}

qui a une certaine forme de validation des attributs:

public class Product
{
    public int Id { get; set; }

    [NotEmpty, NotShorterThan10Characters, NotLongerThan100Characters]
    public string Name { get; set; }

    [NotLessThan0]
    public decimal Price { get; set;}
}

Comme vous pouvez le voir, j'ai fait ces attributs complètement. Qui de validation (NHibernate Validateur, DataAnnotations, ValidationApplicationBlock, Château du programme de validation, etc) utilisé ici n'est pas important.

Dans ma couche client, j'ai aussi une installation standard où je n'utilise pas le Domaine entités elles-mêmes, mais plutôt de la carte à Viewmodel (aka DTO) qui de mon point de vue de la couche d'utilisations:

public class ProductViewModel
{
    public int Id { get; set; }

    public string Name { get; set; }

    public decimal Price { get; set;}
}

Nous allons ensuite de dire que je veux que mon client/vue d'être en mesure d'effectuer quelques niveau de la propriété des validations.

La seule façon dont je le vois je peux faire c'est de répéter la validation des définitions dans le ViewModel objet:

public class ProductViewModel
{
    public int Id { get; set; }

    // validation attributes copied from Domain entity
    [NotEmpty, NotShorterThan10Characters, NotLongerThan100Characters]
    public string Name { get; set; }

    // validation attributes copied from Domain entity
    [NotLessThan0]
    public decimal Price { get; set;}
}

Ce n'est clairement pas satisfaisante, comme je l'ai répété la logique d'entreprise (niveau de la propriété de validation) dans le ViewModel (DTO) de la couche.

Donc, ce qui peut être fait?

En supposant que j'utilise un outil d'automatisation comme AutoMapper à la carte de mon Domaine entités à mon ViewModel Otd, ne serait-il pas également être cool de faire en quelque sorte de transfert de la logique de validation pour les propriétés qui sont mappées à la ViewModel ainsi?

Les questions sont:

1) Est-ce une bonne idée?

2) dans l'affirmative, peut-il être fait? Si non, quelles sont les solutions de rechange, le cas échéant?

Je vous remercie à l'avance pour toute entrée!

11voto

Sam Points 2561

Si vous utilisez quelque chose qui prend en charge DataAnnotations, vous devriez pouvoir utiliser une classe de métadonnées pour contenir vos attributs de validation:

 public class ProductMetadata 
{
    [NotEmpty, NotShorterThan10Characters, NotLongerThan100Characters]
    public string Name { get; set; }

    [NotLessThan0]
    public decimal Price { get; set;}
}
 

et ajoutez-le dans MetadataTypeAttribute à la fois sur l'entité de domaine et DTO:

 [MetadataType(typeof(ProductMetadata))]
public class Product
 

et

 [MetadataType(typeof(ProductMetadata))]
public class ProductViewModel
 

Cela ne fonctionnera pas avec tous les validateurs - vous devrez peut-être étendre le cadre de validation de votre choix pour implémenter une approche similaire.

9voto

Neal Points 2286

Le but de la validation est de s'assurer que les données qui arrivent dans votre application répond à certains critères, avec cela à l'esprit, le seul endroit où il fait sens pour valider la propriété de contraintes, comme ceux que vous avez identifiés ici, est sur le point où vous accepter des données provenant d'une source non fiable ( c'est à dire l'utilisateur ).

Vous pouvez utiliser quelque chose comme "de l'argent motif" d'élever la validation de votre type de domaine du système et l'utilisation de ces types de domaine dans le modèle de vue où il fait sens. Si vous avez une validation plus complexe (c'est à dire l'expression de règles métier qui exigent plus de connaissances que celle exprimée dans une seule propriété), elles appartiennent à des méthodes sur le modèle de domaine qu'appliquer les modifications.

En bref, mettre de la validation des données d'attributs sur les modèles de vue et de les laisser hors de votre domaine de modèles.

4voto

Martin Su Points 1163

Il s'avère que AutoMapper peut être capable de faire cela pour nous automatiquement, ce qui est le meilleur des cas.

AutoMapper-utilisateurs: Transfert des attributs de validation pour le viewmodel?
http://groups.google.com/group/automapper-users/browse_thread/thread/efa1d551e498311c/db4e7f6c93a77302?lnk=gst&q=validation#db4e7f6c93a77302

Je n'ai pas eu l'occasion d'essayer les solutions proposées là, mais l'intention de peu de temps.

4voto

JontyMC Points 1156

Pourquoi ne pas utiliser une interface pour exprimer votre intention? Par exemple:

 public interface IProductValidationAttributes {
    [NotEmpty, NotShorterThan10Characters, NotLongerThan100Characters]
    string Name { get; set; }

    [NotLessThan0]
    decimal Price { get; set;}
}
 

1voto

ASharp Points 174

Si vous utilisez des entités de domaine manuscrites, pourquoi ne pas placer vos entités de domaine dans leur propre assembly et utiliser ce même assembly à la fois sur le client et le serveur. Vous pouvez réutiliser les mêmes validations.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X