199 votes

Différence entre le référentiel et la couche de Service ?

En poo, Design Patterns, quelle est la différence entre le modèle de référentiel et d’une couche de Service ?

Je travaille sur une application ASP.NET MVC 3 et j’essaie de comprendre ces modèles de conception, mais mon cerveau est tout simplement pas obtenir it... encore !!

342voto

LukLed Points 18010

Dépôt de la Couche vous donne un niveau supplémentaire d'abstraction au-dessus d'accès aux données. Au lieu d'écrire

var context = new DatabaseContext();
return CreateObjectQuery<Type>().Where(t => t.ID == param).First();

pour obtenir un seul article de la base de données, vous utilisez référentiel d'interface

public interface IRepository<T>
{
    IQueryable<T> List();
    bool Create(T item);
    bool Delete(int id);
    T Get(int id);
    bool SaveChanges();
}

et appelez - Get(id). Dépôt de la couche expose de base CRUD opérations.

La couche de Service expose la logique d'entreprise, qui utilise le référentiel. Exemple de service qui pourrait ressembler à:

public interface IUserService
{
    User GetByUserName(string userName);
    string GetUserNameByEmail(string email);
    bool EditBasicUserData(User user);
    User GetUserByID(int id);
    bool DeleteUser(int id);
    IQueryable<User> ListUsers();
    bool ChangePassword(string userName, string newPassword);
    bool SendPasswordReminder(string userName);
    bool RegisterNewUser(RegisterNewUserModel model);
}

Alors qu' List() méthode de référentiel renvoie à tous les utilisateurs, ListUsers() de IUserService pourrait renvoyer uniquement, l'utilisateur a accès.

Dans ASP.NET MVC + EF + SQL SERVER, j'ai ce flux de communication:

Vues <- Contrôleurs -> couche de Service -> Dépôt de la couche -> EF -> SQL Server

La couche de Service -> Dépôt de la couche -> EF Cette partie fonctionne sur les modèles.

Vues <- Contrôleurs -> couche de Service de Cette partie fonctionne sur les modèles de vue.

EDIT:

Exemple de flux de /Commandes/ByClient/5 (nous voulons voir l'ordre de client spécifique):

public class OrderController
{
    private IOrderService _orderService;

    public OrderController(IOrderService orderService)
    {
        _orderService = orderService; // injected by IOC container
    }

    public ActionResult ByClient(int id)
    {
        var model = _orderService.GetByClient(id);
        return View(model); 
    }
}

C'est l'interface de commande de service:

public interface IOrderService
{
    OrdersByClientViewModel GetByClient(int id);
}

Cette interface renvoie au modèle de vue:

public class OrdersByClientViewModel
{
     CientViewModel Client { get; set; } //instead of ClientView, in simple project EF Client class could be used
     IEnumerable<OrderViewModel> Orders { get; set; }
}

C'est l'implémentation de l'interface. Il utilise des classes de modèle et de référentiel pour créer de modèle de vue:

public class OrderService : IOrderService
{
     IRepository<Client> _clientRepository;
     public OrderService(IRepository<Client> clientRepository)
     {
         _clientRepository = clientRepository; //injected
     }

     public OrdersByClientViewModel GetByClient(int id)
     {
         return _clientRepository.Get(id).Select(c => 
             new OrdersByClientViewModel 
             {
                 Cient = new ClientViewModel { ...init with values from c...}
                 Orders = c.Orders.Select(o => new OrderViewModel { ...init with values from o...}     
             }
         );
     }
}

44voto

Mikael Eliasson Points 2962

Comme Carnotaurus, a déclaré le référentiel est responsable de la cartographie de vos données à partir du format de stockage à vous de business objects. Il doit gérer à la fois la façon de lire et écrire des données(delete, update trop) de et vers l'espace de stockage.

Le but de la couche de service sur l'autre main est d'encapsuler la logique métier en un seul lieu afin de promouvoir la réutilisation du code et de la séparation des préoccupations. Ce que cela signifie, en général, pour moi, dans la pratique, lors de la construction de Asp.net MVC sites, c'est que j'ai cette structure

[Controller] appelle [Service(s)] qui appelle [référentiel(s)]

Un principe que j'ai trouvé utile est de maintenir la logique à un minimum dans les contrôleurs et les référentiels.

Dans les contrôleurs, c'est qu'il permet de me tenir au SEC. Il est très courant que j'ai besoin d'utiliser le même filtrage ou de la logique quelque part d'autre et si je l'ai placé dans le contrôleur, je ne peux pas le réutiliser.

Dans les dépôts, c'est parce que je veux être en mesure de remplacer mon stockage(ou ORM) quand quelque chose de mieux. Et si j'ai de la logique dans le référentiel, et j'ai besoin de réécrire cette logique lorsque je modifie le référentiel. Si mon référentiel renvoie uniquement IQueryable et le service ne le filtrage sur l'autre main, je vais seulement besoin de remplacer les mappages.

Par exemple, récemment, j'ai remplacé plusieurs de mes Linq-to-Sql dépôts avec EF4 et ceux où j'étais resté fidèle à ce principe pourrait remplacé dans une affaire de minutes. Où j'ai eu un peu de logique, c'était une question d'heures plutôt.

8voto

Carnotaurus Points 1861

Généralement, un référentiel est utilisé comme échafaudage pour remplir vos entités - une couche de service allait sortir et la source d’une requête. Il est probable que vous mettriez un référentiel sous la couche de votre service.

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