Je travaille sur une architecture e-tier au sein de la structure MVC (ASP.NET MVC5, Entity Framework 6). Mon application est divisée en trois sous-projets: couche métier, couche access-données, référentiel (y compris référentiel et unité de travail) et application Web ASP.NET MVC. J’ai du mal à comprendre le mappage entre les données commerciales et le modèle de structure d’entité. par exemple, si j’ai la classe de modèle User dans le entity framework
[Table("User")] public class User { public User() { } [Key] public int UserID { get; set; } [SsortingngLength(250)] [Required] public ssortingng FirstName { get; set; } [SsortingngLength(250)] [Required] public ssortingng LastName { get; set; } [Required] public int Age { get; set; } [SsortingngLength(250)] [Required] public ssortingng EmailAddress { get; set; } public ICollection UserInGroup { get; set; } }
et dans la couche métier, j’ai classe d’utilisateurs
public class User { private ssortingng userID; private ssortingng firstName; private ssortingng lastName; private int age; private ssortingng emailAddress; public ssortingng UserID { get { return userID; } set { userID = value; } } public ssortingng FirstName { get { return firstName; } set { firstName = value; } } public ssortingng LastName { get { return lastName; } set { lastName = value; } } public int Age { get { return age; } set { age = value; } } public ssortingng EmailAddress { get { return emailAddress; } set { emailAddress = value; } } public void GetAllUser() { List _user = new List(); using (var _uow = new UserManagement_UnitOfWork()) { _user = (from u in _uow.User_Repository.GetAll() select u).ToList(); } } }
Comment je mappe ensemble et deuxièmement; En référence à la méthode GetAllUser (), je dois toujours utiliser la classe de modèle utilisateur de DAL afin d’obtenir tous les utilisateurs de la firebase database, où se trouvent actuellement mes connaissances; chaque couche doit être indépendante l’une de l’autre et j’ai une couche d’abstraction, c’est-à-dire un référentiel entre la couche d’access aux données et la couche de gestion. Je suis un peu confus du fait que les deux concepts travaillent ensemble. Suis-je sur la bonne voie ou manque quelque chose. besoin également de réponse pratique sur la couche de gestion utilisateur.
Vous pouvez simplement le faire en utilisant AutoMapper Installez-le via Nuget:
PM> Install-Package AutoMapper
et tout ce que vous avez à faire est de configurer AutoMapper pour mapper des objects similaires à votre place.
Mapper.CreateMap();
Vous pouvez convertir des objects n’importe où comme ceci:
BLL.User bll_User = Mapper.Map(dal_user);
Votre question concerne davantage le design / l’architecture, qui n’a pas de solution unique. Je peux tout au plus partager quelques suggestions et que vais-je faire habituellement dans une stack ASP.NET MVC + Entity Framework assez typique:
BLL.User
le principe de responsabilité unique. Votre classe BLL.User
ne doit pas se préoccuper de la façon de récupérer DAL.User
de la firebase database via Entity Framework / Unit of Work. Vous devriez simplement avoir une autre classe / couche qui sera responsable de cela:
public interface IUserRepository { IEnumerable GetAllUsers(); }
Puis une autre classe pour implémenter IUserRepository
:
public class UserRepository : IUserRepository { private readonly UserManagement_UnitOfWork _unitOfWork; public UserRepository(UserManagement_UnitOfWork unitOfWork) { _unitOfWork = unitOfWork; } public IEnumerable GetAllUsers() { return from u in _unitOfWork.User_Repository.GetAll() select u; } }
Cela supprime la dépendance de votre utilisateur BLL.User
à la classe UserManagment_UnitOfWork
et facilite les tests / moquages (des tests unitaires peuvent être écrits pour IUserRepository
mémoire).
Ensuite, à partir de votre contrôleur, chaque fois qu’il est nécessaire de récupérer BLL.Users
, vous injectez simplement une instance de IUserRepository
dans le constructeur du contrôleur:
public class UserController { private readonly IUserRepository _userRepository; public UserController(IUserRepository userRepository) { _userRepository = userRepository; } public ActionResult Index() { // Simple example using IEnumerable as the view model return View(_userRepository.GetAllUsers().ToList()); } }
DAL.User
à BLL.User
C’est en fait assez similaire au point 1, vous pouvez simplement avoir une autre paire interface / classe:
public interface IUserMapper { BLL.User MapUser(DAL.User); } public class UserMapper : IUserMapper { public BLL.User MapUser(DAL.User user) { return new BLL.User { FirstName = user.FirstName, LastName = user.LastName, Age = user.Age // etc... }; } }
Ou, si vous pensez que l’écriture de code de mappage est fastidieuse, envisagez d’utiliser AutoMapper pour que votre code devienne Mapper.Map
private
dans BLL.User
et les convertir en propriétés automatiques. ValidationAtsortingbute
pour faciliter la validation dans votre application ASP.NET MVC. public class User { public ssortingng UserId { get; set; } [Required] public ssortingng FirstName { get; set; } public ssortingng LastName { get; set; } [Range(0, int.MaxValue)] public int Age { get; set; } [EmailAddress] public ssortingng EmailAddress { get; set; } }
Tout d’abord, il n’y a pas besoin de couche de référentiel ni de couche d’access aux données. Ces deux couches ont le même objective: append une couche d’abstraction pour utiliser votre stockage persistant. Bien qu’ils aient des concepts différents
GetAll
, etc. Il s’agit d’une description très simplifiée, mais les ressources disponibles concernant ce modèle sont suffisantes, par exemple . GetUserByName
, GetUserById
, RemoveUser
, GetAllActiveUsers
, etc. De plus, l’unité de travail ne doit pas nécessairement être implémentée dans le référentiel / DAL. Puisqu’une même unité de travail peut contenir la modification de plusieurs entités ou des demandes à des services externes. À mon avis, BLL serait un endroit plus approprié pour UoW car, dans la plupart des cas, vous pouvez considérer une seule action commerciale (une méthode dans BL) comme un UoW.
Maintenant, quand c’est un peu plus clair ( j’espère ). Votre référentiel / DAL doit renvoyer uniquement les entités commerciales et non les classes générées par la firebase database (si elles sont différentes) et toute la logique de mappage doit être encapsulée dans les couches de référentiel / DAL. Par exemple, la méthode GetUserById
doit renvoyer une BLL - User Class
et non une classe utilisateur générée par EF dans ce cas, qui peut être une classe interne de la couche Repository / DAL.
Pour gérer les mappages entre ces classes, vous pouvez utiliser différentes bibliothèques telles que ValueInjecter ou AutoMapper, qui sont vraiment géniales et peuvent faciliter votre développement.