I would like to start by mentioning that I am LAMP stack guy who happens to be making my first ever .NET C# web app and I'm seeking general advises for best practices and to see how more experienced people would have done it.
I am using code first development pattern with latest Entity Framework . I have a AppUser
model. The user could be on of few types, one of them is employee
.
public class AppUser{
public int Id { get; set; }
public UserType Type { get; set; }
public Title Title { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public virtual AddressDetails AddressDetails { get; set; }
public virtual Company Company { get; set; }
..................................................
}
public class AddressDetails
{
public int Id { get; set; }
public string AddressLine { get; set; }
public string City { get; set; }
public string County { get; set; }
public string PostCode { get; set; }
public float Latitude { get; set; }
public float Longtitude { get; set; }
[JsonIgnore]
public virtual AppUser User { get; set; }
}
I believe that smaller methods are the better. So, I am trying to keep controllers as small as possible. I made classes which handles all interactions with database and keeps business logic out of Models and Controllers. First class is abstract MasterRepository
,which has logic for Database Update/Add/SaveChanges. All other "repositories" inherit it.
( "AppDB" is inheriting from DbContext and holds all DbSets)
public abstract class MasterRep
{
protected AppDB _db { get; set; }
protected AppUser _currentUser { get; set; }
protected int _companyId { get; set; }
protected string _applicationUserId { get; set; }
public MasterRep(string applicationUserId, AppDB db = null)
{
_db = db ?? new AppDB ();
_currentUser = GetUserByApplicationId(applicationUserId);
_companyId = _currentUser.Company.Id;
_applicationUserId = applicationUserId;
}
}
.........................................
Each model has it own "repository". So, User
of type "employee" has:
public class EmployeeRep : UserRep
{
public EmployeeRep(string applicationUserId, AppDB db = null) : base(applicationUserId, db) { }
private IEnumerable<AppUser> Employees
{
get
{
IEnumerable<AppUser> employees = _db.AppUsers.Where(
r =>
r.Company.Id == _companyId &&
r.Type == UserType.Employee &&
r.IsDeleted == false
);
return employees;
}
}
public User GetById(int Id)
{
User employee = Employees.FirstOrDefault(r =>
r.Id == Id
);
return employee;
}
.......................
The EmployeeRep
holds all logic for getting/updating all employees.
And here is example of retrieving a single employee in controller
public class HomeController : Controller
{
private EmployeeRep _employeeRep { get; set; }
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
base.Initialize(requestContext);
_employeeRep = (User.Identity.GetUserId() != null) ? new EmployeeRep(User.Identity.GetUserId()) : null;
}
public ActionResult Index(int id)
{
NHUser currentUser = _employeeRep.CurrentUser;
NHUser employee = _employeeRep.GetById(id);
ViewBag.CurrentUser = currentUser;
return View(employee );
.............................................
So, controllers are in charge of what get displayed and "Repositories" in charge of all business logic/database interactions. All methods are small and doing only one task. However, I am confused by open source projects which I found on github. It looks like everyone doing their own thing.
Am I on a right track here? What is more common way of achieving same goal? i.e having a separate class which handles data processing.
AppDB
a subclass ofDbContext
? \$\endgroup\$