How to map Entity Framework model classes with Business Layer class in n-tier architecture - ASP.NET-MVC

后端 未结 3 1444
我在风中等你
我在风中等你 2021-02-10 03:13

I am working on e-tier architecture within MVC framework (ASP.NET MVC5, Entity Framework 6). My application is divided into three sub-projects which are Business-Layer, Data-Acc

3条回答
  •  甜味超标
    2021-02-10 03:35

    Your question is more about design/architecture which does not have a 'one-size-fits-all' solution. I can at most share some suggetions and what will I usually do in a fairly typical ASP.NET MVC + Entity Framework stack:

    1. Make sure your BLL.User class obeys the Single Responsibility Principle

    Your BLL.User class should not concern itself with how to retrieve DAL.User from the database through Entity Framework/Unit of Work. You should simply have another class/layer that will be responsible for that:

    public interface IUserRepository
    {
        IEnumerable GetAllUsers();
    }
    

    Then another class to implement 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;
        }
    }
    

    Doing so removes the dependency from your BLL.User to the UserManagment_UnitOfWork class and facilitates testing/mocking (i.e. unit tests can be written to mock an in-memory IUserRepository)

    Then from your controller, whenever there is a need to retrieve BLL.Users, you simply inject an instance of IUserRepository to the controller's constructor:

    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());
        }
    }
    

    2. How to map DAL.User to BLL.User

    It's actually quite similar to point number 1, you can simply have another interface/class pair:

    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...
             };
        }
    }
    

    Or, if you think writing mapping code is tedious, consider using AutoMapper so that your code becomes Mapper.Map(user)

    Bonus points

    1. You can skip those private fields in BLL.User and convert them to auto-properties
    2. You can add attributes that are derived from ValidationAttribute to aid validation in your ASP.NET MVC application
    public class User
    {
        public string UserId { get; set; }
    
        [Required]
        public string FirstName { get; set; }
    
        public string LastName { get; set; }
    
        [Range(0, int.MaxValue)]
        public int Age { get; set; }
    
        [EmailAddress]
        public string EmailAddress { get; set; }
    }
    

提交回复
热议问题