2009-08-21 7 views
1

Je suis un peu confus au sujet de la couche de service et en utilisant la validation.Questions sur la couche de service en tant que validation dans asp.net mvc

Je cherche donc à travers ce tutoriel: http://www.asp.net/learn/mvc/tutorial-38-cs.aspx

Tout d'abord si vous regardez la liste 3

using System.Collections.Generic; 
using System.Web.Mvc; 

namespace MvcApplication1.Models 
{ 
    public class ProductService : MvcApplication1.Models.IProductService 
    { 

     private ModelStateDictionary _modelState; 
     private IProductRepository _repository; 

     public ProductService(ModelStateDictionary modelState, IProductRepository repository) 
     { 
      _modelState = modelState; 
      _repository = repository; 
     } 

     protected bool ValidateProduct(Product productToValidate) 
     { 
      if (productToValidate.Name.Trim().Length == 0) 
       _modelState.AddModelError("Name", "Name is required."); 
      if (productToValidate.Description.Trim().Length == 0) 
       _modelState.AddModelError("Description", "Description is required."); 
      if (productToValidate.UnitsInStock < 0) 
       _modelState.AddModelError("UnitsInStock", "Units in stock cannot be less than zero."); 
      return _modelState.IsValid; 
     } 

     public IEnumerable<Product> ListProducts() 
     { 
      return _repository.ListProducts(); 
     } 

     public bool CreateProduct(Product productToCreate) 
     { 
      // Validation logic 
      if (!ValidateProduct(productToCreate)) 
       return false; 

      // Database logic 
      try 
      { 
       _repository.CreateProduct(productToCreate); 
      } 
      catch 
      { 
       return false; 
      } 
      return true; 
     } 


    } 

    public interface IProductService 
    { 
     bool CreateProduct(Product productToCreate); 
     IEnumerable<Product> ListProducts(); 
    } 
} 

Ils même interface juste avec un nom différent essentiellement pourquoi ne pas simplement utiliser un?

public interface IProductRepository 
    { 
     bool CreateProduct(Product productToCreate); 
     IEnumerable<Product> ListProducts(); 
    } 

    public interface IProductService 
    { 
     bool CreateProduct(Product productToCreate); 
     IEnumerable<Product> ListProducts(); 
    } 

Dans mon livre, si (l'auteur qui je pense a écrit ce tutoriel) a changé d'avoir IProductRepository d'annuler. Cela me rend encore plus confus.

Alors quelqu'un peut-il expliquer pourquoi j'ai besoin de 2 interfaces qui semblent faire la même chose?

Mes questions suivantes sont mon référentiel a une fonction de suppression. Est-ce que je mets aussi celui-ci dans ma couche Service (je suppose que c'est obligatoire si vous utilisez une interface mais si vous utilisez 2 comme ça, alors ça pourrait être optinal).

Alors qu'est-ce que j'aurais dans ma couche de service? Serait-il juste appeler la fonction de suppression dans le référentiel? Est-ce que ce devrait juste être une méthode nulle ou devrait-elle retourner bool? Je ne pense pas que pour cette méthode toute validation devrait être faite? Donc je ne suis pas sûr si un bool serait nécessaire.

Répondre

1

du tutoriel que vous lisez:

Ainsi, la logique de contrôle de flux d'application appartient à un contrôleur et des données logique d'accès appartient à un référentiel. Dans ce cas, où mettez-vous votre logique de validation ? Une option consiste à placer votre logique de validation dans une couche de service .

une couche de service est une couche supplémentaire dans une application ASP.NET MVC que médie communication entre un contrôleur et la couche de stockage. La couche de service contient la logique métier. En particulier, il contient la validation logique.

EDIT:

Je ne sais pas si je peux vous l'expliquer de façon claire (parce que je ne suis pas couramment l'anglais), mais je vais essayer:

A couche de service est une couche supplémentaire dans une application ASP.NET MVC qui sert de médiateur de communication entre un contrôleur et une couche de référentiel, en ce sens que vous pouvez gérer à la fois la validation et le bus d'application. Parfois, votre service devra travailler avec deux ou plusieurs méthodes de sa couche de référentiel correspondant, de sorte qu'il n'a pas besoin d'avoir la même interface.

Un exemple de base, pensons que vous avez un formulaire de registre.

vous aurez les interfaces suivantes

public interface IUserService 

{ 
    bool Register(User mUser); 
    bool Validate(User mUser); 
} 

public interface IUserRepository 
{ 
    User FindUserByEmail(string Email); 
    bool Insert(User mUser); 
} 

donc vous retrouver avec deux classes qui fera quelque chose comme: public class UserRepository: IUserRepository {

User FindUserByEmail(string Email) 
{ 
    //do a ninja search and return an user or null 
} 
    bool Insert(User mUser); 
    { 
     //Insert user into db 
    } 
} 

public class UserService: IUserService 
{ 
    public bool Validate(User mUser) 
    { 
     //validate user 
    } 
    IUserRepository _respository = new UserRepository(); 
    bool Register(User mUser) 
    { 
     if(Validate(mUser); 
     var hasUser = _respository.FindUserByEmail(User.Email); 
     if(hasUser==null) 
      return _respository.Insert(mUser); 
     return false; 
    } 
} 
+0

Désolé je ne suis pas. Je ne vois toujours pas pourquoi vous ne pouvez pas utiliser la même interface et faites à la place 2 interfaces différentes qui ont exactement les mêmes méthodes. Toujours pas sûr de la supprimer soit il devrait être de retour quelque chose ou non? – chobo2

+0

chobo2, j'ai édité ma réponse pour expliquer ce que cela signifie pour vous (il m'a fallu si longtemps pour écrire LOL) – Cleiton

+0

Cela aide beaucoup. Et si vous deviez appeler un autre référentiel? L'appelleriez-vous dans la couche de service ou l'appelleriez-vous dans votre contrôleur? – chobo2

0

Je pense que vous avez a fait valoir un argument pour une interface unique dans ce cas limité, mais le service et les référentiels remplissent deux fonctions très différentes et vous pourriez rencontrer des problèmes plus tard s'ils partageaient une seule interface.

Que faire si le CreateProduct() ou ListProducts() avait besoin de différentes signatures de méthode dans le service ou le référentiel? Que faire si ValidateProduct() doit être défini dans l'interface? Le référentiel ne devrait certainement pas avoir à implémenter cela. Comme vous l'avez souligné, il n'y a pas besoin de deux interfaces qui définissent la même chose dans cet exemple particulier, mais je suppose que l'auteur présume que, à terme, elles seraient différentes et donc nécessaires.

+0

Hmm, je vois en quelque sorte votre point de vue, mais je pense que j'aurais besoin de plus d'un exemple. J'essaye de penser pourquoi CreateProduct aurait une signature de méthode différente. Comme la couche de service se connecte au référentiel de toute façon et si vous allez créer un produit, il doit avoir ces champs qui correspondent à la base de données. Donc, je ne vois pas ce que CreateProduct enverrait différemment dans un produit qui doit être créé avec ces champs. – chobo2

+0

D'un côté, pas l'exemple qu'il donne dans son livre (je pense que ce tutoriel a été écrit par le gars qui a écrit asp.net mvc unleashed). Il n'a même pas de ValidateProduct(). Il a fait la validation directement dans la méthode Create. – chobo2

+0

J'ai mal lu le code au début (Validate ... est une méthode protégée seulement appelée dans la méthode Create) donc c'est pourquoi il ne serait pas dans l'interface dans ce cas. La différence entre son livre et ceci est juste un petit refactoring. –

Questions connexes