I had a technical test with a simple CRUD application where I used n layered architecture as explained on the Patterns In Action book that I bought.
However after delivering one of their feedbacks was the following.
DbContext lifetime is completely wrong. (literally)
I will copy the relevant files on this question, because I want to learn what I did wrong and if that product I bought has just problems conceptually.
So, in my DataAccess
class library I have this:
namespace DataObjects
{
// abstract factory interface. Creates data access objects.
// ** GoF Design Pattern: Factory.
public interface IDaoFactory
{
//Product Dao interface that must be implemented by each provider
IProductDao ProductDao { get; }
//Color Dao interface that must be implemented by each provider
IColorDao ColorDao { get; }
//Size Dao interface that must be implemented by each provider
ISizeDao SizeDao { get; }
//Category Dao interface that must be implemented by each provider
ICategoryDao CategoryDao { get; }
//File Dao interface that must be implemented by each provider
IFileDao FileDao { get; }
//File Error Dao that must be implemented by each interface
IFileErrorDao FileErrorDao { get; }
}
}
Then I have also this Interface
using BusinessObjects;
using System.Collections.Generic;
namespace DataObjects
{
public interface ICategoryDao
{
//Gets a list of categories
List<Category> GetCategories();
//Inserts one category
void InsertCategory(Category category);
//To verify if category exists
bool CategoryExists(string category);
//Get Category by name
Category GetCategoryByName(string category);
}
}
And now, in the EntityFramework namespace I have the following implementations
namespace DataObjects.EntityFramework
{
// Data access object factory
// ** Factory Pattern
public class DaoFactory : IDaoFactory
{
public IProductDao ProductDao => new ProductDao();
public IColorDao ColorDao => new ColorDao();
public ISizeDao SizeDao => new SizeDao();
public ICategoryDao CategoryDao => new CategoryDao();
public IFileDao FileDao => new FileDao();
public IFileErrorDao FileErrorDao => new FileErrorDao();
}
}
DaoCategory
implementation
using AutoMapper;
using System.Collections.Generic;
using System.Linq;
using BusinessObjects;
namespace DataObjects.EntityFramework
{
// Data access object for Product
// ** DAO Pattern
public class CategoryDao : ICategoryDao
{
/// <summary>
/// Inserts category into database
/// </summary>
/// <param name="category"></param>
public void InsertCategory(Category category)
{
using (var context = new ExamContext())
{
Mapper.Initialize(cfg => cfg.CreateMap<Category, CategoryEntity>());
var entity = Mapper.Map<Category, CategoryEntity>(category);
context.CategoryEntities.Add(entity);
context.SaveChanges();
// update business object with new id
category.Id = entity.Id;
}
}
/// <summary>
/// Gets all categories from database
/// </summary>
/// <returns>Returns a list of Category</returns>
public List<Category> GetCategories()
{
using (var context = new ExamContext())
{
Mapper.Initialize(cfg => cfg.CreateMap<CategoryEntity, Category>());
var categories = context.CategoryEntities.ToList();
return Mapper.Map<List<CategoryEntity>, List<Category>>(categories);
}
}
/// <summary>
/// Verifies if one category name exists
/// </summary>
/// <param name="category">Category name</param>
/// <returns>Returns true if exists</returns>
public bool CategoryExists(string category)
{
using (var context = new ExamContext())
{
return context.CategoryEntities.Any(x => x.CategoryName == category);
}
}
/// <summary>
/// Gets color by name
/// </summary>
/// <param name="categoryName">color name</param>
/// <returns>Category</returns>
public Category GetCategoryByName(string categoryName)
{
using (var context = new ExamContext())
{
Mapper.Initialize(cfg => cfg.CreateMap<CategoryEntity, Category>());
var category = context.CategoryEntities.FirstOrDefault(x => x.CategoryName == categoryName);
return Mapper.Map<CategoryEntity, Category>(category);
}
}
}
}