Entity Framework et séparation des couches

12

J'essaie de travailler un peu avec Entity Framework et j'ai une question concernant la séparation des couches.

J'utilise généralement l'approche UI -> BLL -> DAL et je me demande comment utiliser EF ici.

Mon DAL serait généralement quelque chose comme

GetPerson(id)
{
    // some sql
    return new Person(...)
}

BLL:

GetPerson(id)
{
    Return personDL.GetPerson(id)
}

UI:

Person p = personBL.GetPerson(id)

Ma question est maintenant: puisque EF crée mon modèle et DAL, est-ce une bonne idée d'envelopper EF dans mon propre DAL ou est-ce juste une perte de temps?

Si je n'ai pas besoin d'envelopper EF, est-ce que je placerais toujours Model.esmx dans sa propre bibliothèque de classes ou serait-ce bien de le placer à l'intérieur de mon BLL et d'y travailler?

Je ne vois pas vraiment la raison d'envelopper EF dans mon propre DAL mais je veux savoir ce que font les autres.

Donc, au lieu d'avoir ce qui précède, je laisserais de côté le DAL et je ferais simplement:

BLL:

GetPerson(id)
{
    using (TestEntities context = new TestEntities())
    {
            var result = from p in context.Persons.Where(p => p.Id = id)            
                    select p;
    }
}

Que faire?

Thomas
la source

Réponses:

13

L'exemple que vous fournissez n'est pas une architecture en couches. Je sais que c'est intentionnellement simplifié, mais:

Votre couche de présentation est directement liée à l'entité Personne. Ce n'est OK que dans les cas les plus simples, et certainement pas lorsque vous essayez de définir vos calques.

La méthode GetPerson utilise également une assez mauvaise pratique de création d'un nouveau contexte pour chaque appel. Vous devriez obtenir le contexte dans le constructeur, et il sera fourni par votre conteneur IOC.

Une structure simple mais efficace que j'ai utilisée est:

  • Project.Core - contient des modèles de vue et des interfaces.
  • Project.DAL - avec mon EDMX et le code généré.
  • Project.BLL - logique métier.
  • Project.Web - l'application Web elle-même.

Il est important de noter que:

  • Le noyau ne dépend d'aucune autre solution.
  • DAL ne dépend d'aucune autre solution.
  • Project.Web dépend de Core, mais pas de DAL ni de BLL.
  • BLL dépend de Core et DAL.
Boris Yankov
la source
1
Le noyau semble être une couche d'objet métier.
sq33G
C'est à peu près ce que j'utilise également, cependant, j'ajouterais des DLL supplémentaires pour répondre aux déclarations d'interface. De cette façon, vous ne référencez que les interfaces (et utilisez quelque chose comme [url = unit.codeplex.com/[Unity[/url] pour DI) et vous pouvez être sûr qu'il n'y a pas de dépendances étranges que vous avez accidentellement induites.
Ed James
Normalement, sans EF, je crée ma propre classe Person dans une couche "Model", donc j'ai UI, BLL, DAL et Model où: UI connaît BLL et Model. BLL connaît DAL et Model. DLL connaît le modèle. Créez-vous également vos propres "modèles d'affichage" et pourquoi n'utilisez-vous pas simplement ceux générés par EF? (Je sais que cela va à l'encontre de l'architecture en couches, mais combien de fois changez-vous réellement la façon dont vous obtenez les données?)
Thomas
@Thomas enveloppant les modèles de vue dans quelque chose d' abstrait facilitera les tests unitaires.
sq33G
3
model! = voir le modèle
Boris Yankov
2

Vous n'avez pas besoin d'envelopper votre EDMX dans quoi que ce soit.

Si vous pouvez prévoir la possibilité de devoir passer d'EF à une autre approche, vous souhaiterez peut-être étendre vos objets métier (en profitant des classes partielles) pour implémenter des interfaces définies dans une couche d'objet métier distincte.

Ensuite, à partir de votre code, vous ne vous occuperez que de ces interfaces et non des classes générées concrètement. Un petit code de colle pourrait être nécessaire pour maintenir cela ensemble; cela avec l'EDMX peut être votre DAL.

sq33G
la source
Donc, si je ne prévois aucun changement de EF à une autre approche, mon code ci-dessus serait correct? Je n'aurais alors que l'interface utilisateur et BLL (où l'EDMX est dans le BLL)?
Thomas
Ma réponse pragmatique serait oui. Avec l'avertissement que vous voudrez peut-être réellement mettre l'EDMX dans son propre petit assemblage s'il sera grand et surtout statique, de sorte que vous n'aurez pas besoin de le recompiler / redistribuer aussi souvent.
sq33G
Ah, bon point sur la recompilation / redistribution :)
Thomas
2

Il existe deux approches générales de la superposition: la superposition stricte et la superposition détendue.

Une approche strictement stratifiée contraint les composants d'une couche à n'interagir qu'avec les pairs et avec la couche directement en dessous.

Une application en couches détendue relâche les contraintes de sorte qu'un composant peut interagir avec les composants de n'importe quelle couche inférieure.

L'utilisation d'une superposition détendue peut améliorer l'efficacité car le système n'a pas à transférer les appels simples d'une couche à la suivante. D'un autre côté, l'utilisation de couches détendues ne fournit pas le même niveau d'isolation entre les couches et rend plus difficile le remplacement d'une couche inférieure sans affecter les couches supérieures.

Pour les grandes solutions impliquant de nombreux composants logiciels, il est courant d'avoir un grand nombre de composants au même niveau d'abstraction qui ne sont pas cohérents. Dans ce cas, chaque couche peut encore être décomposée en un ou plusieurs sous-systèmes cohésifs. La figure 2 illustre une notation UML (Unified Modeling Language) possible pour représenter des couches composées de plusieurs sous-systèmes.

conclusion: si vous n'avez pas besoin de la couche intermédiaire, perdez-la; toutes les applications ne nécessitent pas la même approche et, en quelque sorte, l'ajout d'une couche uniquement à des fins de superposition entraînera des pénalités sur le coût de la complexité et la maintenance.

omarqa
la source