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