A-t-on besoin d’une Business Layer avec Entity Framework ? (2)

A-t-on besoin d’une Business Layer avec Entity Framework ?
Sommaire : Partie 1 – Partie 2 – Partie 3 – Partie 4
Nous avons vu dans l’article précédent qu’il pouvait être intéressant que notre application comporte une Business Library quand on utilise Entity Framework. Passons maintenant à la mise en œuvre. Pour commencer, quelles qualités doit avoir notre BL ?
- Effectuer l’ensemble des traitements d’intelligence métier de l’application,
- Manipuler des entités métier concrètes,
- Exposer une API claire, homogène et simple à utiliser pour nos clients : les développeurs des couches de présentation,
- Être testable, et permettre de mocker les accès à la base de données,
- Ne pas réinventer la roue et tirer parti des fonctionnalités déjà implémentées dans Entity Framework
Donc ça, c’était pour la théorie. Mais concrètement, comment ça va marcher ?
Présentation du cas pratique : une bédétheque utilisant Entity Framework
Notre application est une BDthèque. Elle sert (roulement de tambour) à gérer une collection de BD. En tant qu’utilisateur, je possède une collection de BDs que je peux acheter, classer dans mes rayons, lire, prêter, noter, etc. Rien de bien exotique. Elle pourra être exposée en tant que site Web, application Windows 8, Windows Phone, peu importe. Pour gérer tout cela, nous avons deux projets : Bedetheque.Entities, qui contient les classes métier. Ex :
namespace Bedetheque.Entities { public class BD { public int Id { get; set; } public string Titre { get; set; } public Author Author { get; set; } public Publisher Publisher { get; set; } } }
Et Bedetheque.DAL, qui contient la couche d’accès aux données minimale :
using System.Data.Entity; using Bedetheque.Entities; namespace Bedetheque.DAL { public class BedetequeContext : DbContext { public DbSet<BD> BDs { get; set; } public DbSet<Author> Authors { get; set; } public DbSet<Publisher> Publishers { get; set; } } }
Pour créer une nouvelle BD avec un nouvel auteur et un nouvel éditeur nativement avec Entity Framework, nous ferions ainsi :
using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; using Bedetheque.DAL; using Bedetheque.Entities; namespace Bedetheque.Business.Tests { [TestClass] public class UnitTest1 { [TestMethod] public void CreateNewBDWithNewAuthorAndNewPublisher() { //Actors Publisher Dargaud = new Publisher { Name = "Dargaud" }; Author JuanDiazCanales = new Author { Name = "Juan Díaz Canale" }; BD Blacksad = new BD { Titre = "Blacksad", Publisher = Dargaud, Author = JuanDiazCanales }; BD expectedBlacksad; //Activities using (BedetequeContext dbActivities = new BedetequeContext()) { dbActivities.Authors.Add(JuanDiazCanales); dbActivities.Publishers.Add(Dargaud); dbActivities.BDs.Add(Blacksad); } //Assertions using(BedetequeContext dbAsserts = new BedetequeContext()) { expectedBlacksad = dbAsserts.BDs.Where(b => b.Titre == "Blacksad").FirstOrDefault(); } Assert.IsNotNull(expectedBlacksad); Assert.AreEqual("Dargaud", expectedBlacksad.Publisher.Name); Assert.AreEqual("Juan Díaz Canale", expectedBlacksad.Author.Name); } } }
Tout ceci marche très bien, mais notre test unitaire, qui joue ici le rôle de la couche de présentation est donc fortement lié à Entity Framework. Dans le prochain article, nous allons voir comment découpler proprement la couche de présentation de la couche d’accès aux données.