I am creating a Ntier solution which includes Domain Objects, DataAccess Layer,Service layer and the web API layer . I am using AutoMapper to map Dtos and domain objects in the service layer. I would like to know how to write the logic for performing CRUD operations in the service layer. I have written some mapping. Is this the right way of mapping or is there a better way to do it and also please do correct me where I have written the get, save, update, delete operation. I basically need help in implementing my Service layer.
I am getting the following error when I debug the code:
Mapper not initialized. Call Initialize with appropriate configuration. If you are trying to use mapper instances through a container or otherwise, make sure you do not have any calls to the static Mapper.Map methods, and if you're using ProjectTo or UseAsDataSource extension methods, make sure you pass in the appropriate IConfigurationProvider instance.
I get the error at the following line of code in the GetPatient method:
yield return Mapper.Map<PatientDto>(patient);
Domain layer
public class Patient : BaseEntity
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public char Gender { get; set; }
public string Phone { get; set; }
}
DataAccess Layer
public class GenericRepository<TEntity> where TEntity : class
{
#region Private member variables...
internal AppointmentBookingContext Context;
internal DbSet<TEntity> DbSet;
#endregion
#region Public Constructor...
/// <summary>
/// Public Constructor,initializes privately declared local variables.
/// </summary>
/// <param name="context"></param>
public GenericRepository(AppointmentBookingContext context)
{
this.Context = context;
this.DbSet = context.Set<TEntity>();
}
#endregion
#region Public member methods...
/// <summary>
/// generic Get method for Entities
/// </summary>
/// <returns></returns>
public virtual IEnumerable<TEntity> Get()
{
IQueryable<TEntity> query = DbSet;
return query.ToList();
}
/// <summary>
/// Generic get method on the basis of id for Entities.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public virtual TEntity GetByID(object id)
{
return DbSet.Find(id);
}
/// <summary>
/// generic Insert method for the entities
/// </summary>
/// <param name="entity"></param>
public virtual void Insert(TEntity entity)
{
DbSet.Add(entity);
}
/// <summary>
/// Generic Delete method for the entities
/// </summary>
/// <param name="id"></param>
public virtual void Delete(object id)
{
TEntity entityToDelete = DbSet.Find(id);
Delete(entityToDelete);
}
/// <summary>
/// Generic Delete method for the entities
/// </summary>
/// <param name="entityToDelete"></param>
public virtual void Delete(TEntity entityToDelete)
{
if (Context.Entry(entityToDelete).State == EntityState.Detached)
{
DbSet.Attach(entityToDelete);
}
DbSet.Remove(entityToDelete);
}
/// <summary>
/// Generic update method for the entities
/// </summary>
/// <param name="entityToUpdate"></param>
public virtual void Update(TEntity entityToUpdate)
{
DbSet.Attach(entityToUpdate);
Context.Entry(entityToUpdate).State = EntityState.Modified;
}
/// <summary>
/// generic method to get many record on the basis of a condition.
/// </summary>
/// <param name="where"></param>
/// <returns></returns>
public virtual IEnumerable<TEntity> GetMany(Func<TEntity, bool> where)
{
return DbSet.Where(where).ToList();
}
/// <summary>
/// generic method to get many record on the basis of a condition but query able.
/// </summary>
/// <param name="where"></param>
/// <returns></returns>
public virtual IQueryable<TEntity> GetManyQueryable(Func<TEntity, bool> where)
{
return DbSet.Where(where).AsQueryable();
}
/// <summary>
/// generic get method , fetches data for the entities on the basis of condition.
/// </summary>
/// <param name="where"></param>
/// <returns></returns>
public TEntity Get(Func<TEntity, Boolean> where)
{
return DbSet.Where(where).FirstOrDefault<TEntity>();
}
/// <summary>
/// generic delete method , deletes data for the entities on the basis of condition.
/// </summary>
/// <param name="where"></param>
/// <returns></returns>
public void Delete(Func<TEntity, Boolean> where)
{
IQueryable<TEntity> objects = DbSet.Where<TEntity>(where).AsQueryable();
foreach (TEntity obj in objects)
DbSet.Remove(obj);
}
/// <summary>
/// generic method to fetch all the records from db
/// </summary>
/// <returns></returns>
public virtual IEnumerable<TEntity> GetAll()
{
return DbSet.ToList();
}
/// <summary>
/// Inclue multiple
/// </summary>
/// <param name="predicate"></param>
/// <param name="include"></param>
/// <returns></returns>
public IQueryable<TEntity> GetWithInclude(
System.Linq.Expressions.Expression<Func<TEntity,
bool>> predicate, params string[] include)
{
IQueryable<TEntity> query = this.DbSet;
query = include.Aggregate(query, (current, inc) => current.Include(inc));
return query.Where(predicate);
}
/// <summary>
/// Generic method to check if entity exists
/// </summary>
/// <param name="primaryKey"></param>
/// <returns></returns>
public bool Exists(object primaryKey)
{
return DbSet.Find(primaryKey) != null;
}
/// <summary>
/// Gets a single record by the specified criteria (usually the unique identifier)
/// </summary>
/// <param name="predicate">Criteria to match on</param>
/// <returns>A single record that matches the specified criteria</returns>
public TEntity GetSingle(Func<TEntity, bool> predicate)
{
return DbSet.Single<TEntity>(predicate);
}
/// <summary>
/// The first record matching the specified criteria
/// </summary>
/// <param name="predicate">Criteria to match on</param>
/// <returns>A single record containing the first record matching the specified criteria</returns>
public TEntity GetFirst(Func<TEntity, bool> predicate)
{
return DbSet.First<TEntity>(predicate);
}
#endregion
}
Service layer
PatientDto.cs
public class PatientDto
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public char Gender { get; set; }
public string Phone { get; set; }
}
AutoMapperConfiguration.cs
public class AutoMapperConfiguration
{
public static void Configure()
{
Assembly[] assemblies = BuildManager.GetReferencedAssemblies().OfType<Assembly>().ToArray();
Mapper.Initialize(cfg =>
cfg.AddProfiles(AllClasses.FromAssemblies(assemblies)
.Where(
a =>
a.FullName.EndsWith("Mapping")))); }
}
DomainToDtoMapping.cs
public class DomainToDtoMapping : Profile
{
public DomainToDtoMapping()
{
CreateMap<BaseEntity, BaseDto>().ReverseMap();
CreateMap<Patient, PatientDto>().ReverseMap();
}
}
IPatientService
public interface IPatientService
{
IEnumerable<PatientDto> GetPatient();
PatientDto GetPatientById(int id);
int CreatePatient(PatientDto customer);
bool UpdatePatient(PatientDto patient);
bool DeletePatient(int patient);
}
PatientService
public class PatientService : IPatientService
{
private readonly IUnitOfWork _unitOfWork;
public int CreatePatient(PatientDto patientDto)
{
using (var scope = new TransactionScope())
{
var patient = _unitOfWork.PatientRepository.GetByID(patientDto.Id);
_unitOfWork.PatientRepository.Insert(patient);
_unitOfWork.Save();
scope.Complete();
return patient.Id;
}
}
public bool DeletePatient(int id)
{
var success = false;
if (id > 0)
{
using (var scope = new TransactionScope())
{
var patient = _unitOfWork.PatientRepository.GetByID(id);
if (patient != null)
{
_unitOfWork.PatientRepository.Delete(patient);
_unitOfWork.Save();
scope.Complete();
success = true;
}
}
}
return success;
}
public IEnumerable<PatientDto> GetPatient()
{
var patient = _unitOfWork.PatientRepository.GetAll();
if (patient != null)
{
yield return Mapper.Map<PatientDto>(patient);
}
yield return null;
}
public PatientDto GetPatientById(int id)
{
var patient = _unitOfWork.PatientRepository.GetByID(id);
if (patient != null)
{
return Mapper.Map<PatientDto>(patient);
}
return null;
}
public bool UpdatePatient(PatientDto patientDto)
{
var success = false;
if (patientDto != null)
{
using (var scope = new TransactionScope())
{
var patient = _unitOfWork.PatientRepository.GetByID(patientDto.Id);
if (patient != null)
{
_unitOfWork.PatientRepository.Update(patient);
_unitOfWork.Save();
scope.Complete();
success = true;
}
}
}
return success;
}