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-Access-Layer, Repository (This include repository and Unit of Work) and ASP.NET MVC web-app. I am struggling to understand mapping between business data and entity framework model. for example if I have model class User in entity framework as
[Table("User")]
public class User
{
public User() { }
[Key]
public int UserID { get; set; }
[StringLength(250)]
[Required]
public string FirstName { get; set; }
[StringLength(250)]
[Required]
public string LastName { get; set; }
[Required]
public int Age { get; set; }
[StringLength(250)]
[Required]
public string EmailAddress { get; set; }
public ICollection<UserInGroup> UserInGroup { get; set; }
}
and in business layer I have user class
public class User
{
private string userID;
private string firstName;
private string lastName;
private int age;
private string emailAddress;
public string UserID
{
get { return userID; }
set { userID = value; }
}
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
public int Age
{
get { return age; }
set { age = value; }
}
public string EmailAddress
{
get { return emailAddress; }
set { emailAddress = value; }
}
public void GetAllUser()
{
List<App.DAL.Model.User> _user = new List<DAL.Model.User>();
using (var _uow = new UserManagement_UnitOfWork())
{
_user = (from u in _uow.User_Repository.GetAll()
select u).ToList();
}
}
}
How I map together and secondly; referring to method GetAllUser(), I still need to use User model class from DAL in order to get all the users from database, where is my current understanding is; each layer should be independent to each other and I have abstraction layer i.e. repository between data access layer and business layer. I am slightly confused of both concept working together. Am I on right track or missing something. also need practical answer on User business layer.
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:
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<User> 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<User> 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<BLL.User> as the view model
return View(_userRepository.GetAllUsers().ToList());
}
}
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<DAL.User, BLL.User>(user)
private
fields in BLL.User
and convert them to auto-propertiesValidationAttribute
to aid validation in your ASP.NET MVC applicationpublic 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; }
}
You can simply do this by using AutoMapper Install it via Nuget:
PM> Install-Package AutoMapper
and then all you have to do is to config AutoMapper to map similar objects for you.
Mapper.CreateMap<DAL.User, BLL.User>();
You can convert objects anywhere like this :
BLL.User bll_User = Mapper.Map<DAL.User, BLL.User>(dal_user);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With