Question

À l'heure actuelle, j'ai une application Web ASP MVC le long d'un projet de modèles, d'un projet de service, d'un projet d'utilitaires et de quelques projets de plaques de données qui fonctionnent comme un référentiel pour un ou plusieurs modèles de domaine. Je suis assez content de la séparation de chaque couche, mais je suis coincé sur ce qu'il faut revenir de la couche de service à l'application Web.

Par exemple, lorsqu'un utilisateur essaie de s'inscrire, un registreViewModel est reçu par le contrôleur. Les pièces individuelles (e-mail, mot de passe, etc.) sont envoyées à la couche de service qui construisent l'objet de domaine membre avec GUID, statut, création, etc. / Membre / {GUID}.

Mais comment la couche de service devrait-elle informer l'application Web si un e-mail existe déjà? Dans une situation plus complexe, je devrai peut-être vérifier l'existence / validité de plusieurs objets de domaine et règles métier, il faudrait donc retourner plusieurs erreurs en une seule fois. De plus, je ne veux pas exception pour bulles sur la couche Web afin que la couche de service piège toutes les exceptions, mais je dois informer la couche Web.

Même si je trouve un moyen de retourner tout cela, la couche Web serait accablée pour traiter tout cela et fournir à l'utilisateur divers commentaires. Le code du contrôleur serait volumineux et l'erreur se préparait. Y a-t-il une meilleure pratique sur le résultat du service à la présentation? Dois-je éliminer la couche de service séparée et avoir le code à l'intérieur du contrôleur? Toutes les pensées sont les bienvenues.

Était-ce utile?

La solution

J'ai écrit le modèle d'opération bibliothèque à cet effet, qui vous permet d'écrire du code comme ceci:

public OperationResult Register(RegisterInput input) {

   var errors = new ErrorBuilder();

   if (errors.NotValid(input) // Invoke DataAnnotations validation
      || errors.Not(this.repo.FindUserByEmail(input.Email) == null, "Email '{0}' already exists.", () => input.Email))
      return errors;

   // Do stuff

   return HttpStatusCode.OK;
}

... et dans le contrôleur, les messages d'erreur sont copiés sur ModelState:

[HttpPost]
public ActionResult Register(RegisterInput input) {

   var result = this.service.Register(input);

   if (result.IsError)
      return View().WithErrors(result);

   // Do stuff
}

Consultez le code source du MVCACTACT Projet qui est écrit en utilisant ce modèle.

Autres conseils

Tout d'abord, vous devez décider si vous écrivez ou non la couche de service à des fins de distribution.

Si vous ne prévoyez pas de distribuer la couche de service à un processus / machine différent,

  1. Créer une classe de messages
  2. Créez un tableau de classes de messages et stockez-le dans httpContext.items
  3. Ajoutez maintenant un nouveau message dans n'importe quelle couche à ce tableau
  4. Consommez-le dans les vues / contrôleur

HttpContext.items est disponible pour la durée de vie de la demande et vous pouvez l'utiliser jusqu'à des vues.

Si vous utilisez un framework DI, vous pouvez réaliser la même chose en utilisant une demande par objet Life Time.

Si vous souhaitez distribuer l'objet, rien de mal à lancer les exceptions de votre couche de service.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top