I have an Entity Framework working with a SQL database. A Web Forms application is currently communicating directly with the Entity Framework model from code behind. I have been tasked with creating a 'middle layer' Business Logic Layer to sit between the UI and DAL (EF).
I have come up with the below for the Person entity. I am looking for advice on ways to improve this structure so I can propagate it throughout the entire project.
The properties for person are the same as the Entity Framework model, all I do is call the conversion methods when I need to convert between the two.
using BLL.Members;
using DAL;
using System;
using System.Collections.Generic;
using System.Data.Entity.Validation;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BLL.People
{
public class Person
{
public int ID { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Salt { get; set; }
public string PasswordKey { get; set; }
public DateTime? Expiry { get; set; }
public string Firstname { get; set; }
public string Surname { get; set; }
public string FullName { get; set; }
public string EmailAddress { get; set; }
public AccountStatus AccountStatus { get; set; }
public DateTime DateCreated { get; set; }
private int CreatedBy { get; set; }
private DateTime LastUpdated { get; set; }
private int LastUpdateBy { get; set; }
public Member Member { get; set; }
private ProjectEntities _context = null;
protected ProjectEntities context
{
get
{
if (_context == null)
_context = new ProjectEntities();
return _context;
}
}
#region Translation
/// <summary>
/// Translates a DAL.Person to BLL.Person
/// </summary>
/// <param name="_person"></param>
/// <returns></returns>
private static Person TranslateEntityToBLLPerson(DAL.Person _person)
{
Person per = new Person();
per.ID = _person.ID;
per.Username = _person.Username;
per.Password = _person.Password;
per.Salt = _person.Salt;
per.PasswordKey = _person.PasswordKey;
per.Expiry = (_person.Expiry == null) ? per.Expiry = null : per.Expiry = _person.Expiry;
per.Firstname = _person.Firstname;
per.Surname = _person.Surname;
per.FullName = _person.FullName;
per.EmailAddress = _person.EmailAddress;
per.AccountStatus = (AccountStatus)_person.AccountStatus;
per.DateCreated = _person.DateCreated;
per.CreatedBy = _person.CreatedBy;
per.LastUpdated = _person.LastUpdated;
per.LastUpdateBy = _person.LastUpdateBy;
per.Member = Member.TranslateEntityToBLLMember(_person.People_Members);
return per;
}
/// <summary>
/// Translates a BLL.Person to DAL.Person
/// </summary>
/// <param name="per"></param>
/// <returns></returns>
private static DAL.Person TranslateBLLPersonToEntity(Person per)
{
DAL.Person _person = new DAL.Person();
_person.ID = per.ID;
_person.Username = per.Username;
_person.Password = per.Password;
_person.Salt = per.Salt;
_person.PasswordKey = per.PasswordKey;
_person.Expiry = (per.Expiry == null) ? _person.Expiry = null : _person.Expiry = _person.Expiry;
_person.Firstname = per.Firstname;
_person.Surname = per.Surname;
_person.FullName = per.FullName;
_person.EmailAddress = per.EmailAddress;
_person.AccountStatus = Convert.ToInt32(per.AccountStatus);
_person.DateCreated = per.DateCreated;
_person.CreatedBy = per.CreatedBy;
_person.LastUpdated = per.LastUpdated;
_person.LastUpdateBy = per.LastUpdateBy;
return _person;
}
#endregion
/// <summary>
/// Adds a new person to the database
/// </summary>
/// <param name="_person"></param>
/// <returns></returns>
public bool addNewPerson(Person _updateBy)
{
DAL.Person newPer = TranslateBLLPersonToEntity(this);
newPer.DateCreated = DateTime.Now;
newPer.CreatedBy = _updateBy.ID;
newPer.LastUpdateBy = _updateBy.ID;
newPer.LastUpdated = DateTime.Now;
context.Entry(newPer).State = System.Data.Entity.EntityState.Added;
try
{
context.SaveChanges();
return true;
}
catch (DbEntityValidationException ex)
{
foreach (var validationErrors in ex.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
}
}
return false;
}
}
/// <summary>
/// Updates a person
/// </summary>
/// <param name="_person"></param>
/// <returns></returns>
public bool updatePerson(Person _updateBy)
{
DAL.Person updatePer = TranslateBLLPersonToEntity(this);
updatePer.LastUpdated = DateTime.Now;
updatePer.LastUpdateBy = _updateBy.ID;
context.Entry(updatePer).State = System.Data.Entity.EntityState.Modified;
try
{
context.SaveChanges();
}
catch (DbEntityValidationException ex)
{
foreach (var validationErrors in ex.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
}
}
}
return true;
}
/// <summary>
/// Retrieve a person by ID
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public static Person fromID(int id)
{
ProjectEntities context = new ProjectEntities();
DAL.Person per = context.People.FirstOrDefault(p => p.ID == id);
if (per != null)
return TranslateEntityToBLLPerson(per);
else
return null;
}
/// <summary>
///
/// </summary>
/// <param name="email"></param>
/// <returns></returns>
public static Person fromEmail(string email)
{
ProjectEntities context = new ProjectEntities();
DAL.Person per = context.People.FirstOrDefault(p => p.EmailAddress == email);
if (per != null)
return TranslateEntityToBLLPerson(per);
else
return null;
}
public bool resetPassword(string _newPassword)
{
var crypto = new SimpleCrypto.PBKDF2();
this.Password = crypto.Compute(_newPassword);
this.Salt = crypto.Salt;
try
{
updatePerson(this);
return true;
}
catch (Exception ex)
{
return false;
}
}
/// <summary>
/// Logs in the user
/// </summary>
/// <param name="_username"></param>
/// <param name="_password"></param>
/// <returns></returns>
public static Person loginPerson(string _username, string _password)
{
ProjectEntities context = new ProjectEntities();
//Initilize the SimpleCrypto
var crypto = new SimpleCrypto.PBKDF2();
//Find the user by the username entered
Person u = TranslateEntityToBLLPerson(context.People.AsNoTracking().FirstOrDefault(p => p.Username == _username));
//If the user exists
if (u != null)
{
//check the account status
if (u.AccountStatus == AccountStatus.PendingEmailVer)
{
//The credentials are not valid, display this to the user
return null;
}
else
{
//Compare the users actual password to an encrypted version of what was entered
if (u.Password == crypto.Compute(_password, u.Salt))
{
u.LastUpdated = DateTime.Now;
u.LastUpdateBy = u.ID;
u.updatePerson(u);
return u;
}
else
{
return null;
}
}
}
else
{
return null;
}
}
}
}
AccountStatus
enum located? in DAL or in BLL? \$\endgroup\$