Would like to ask for a code review for my DAL
. I use Entity framework 6
and Autofac
for dependency injection. All comments will be appreciated.
public interface IBaseEntityObject
{
public int Id {get; set;}
}
public abstract class BaseEntityObject : IBaseEntityObject
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id {get; set;}
}
public class Folder : BaseEntityObject
{
[DataMember]
public string Name {get; set;}
[DataMember]
public List<Letter> Letters {get; set;}
}
public abstract class Letter : BaseEntityObject
{
[DataMember]
public string Title {get; set;}
[DataMember]
public string Content {get; set;}
public virtual Folder Folder {get; set;}
[DataMember]
public int FolderId {get; set;}
[DataMember]
public DateTime CreationDate {get; set;}
}
public class OutgoingLetter : Letter
{
// .. OutgoingLetter properties
}
public class ReceviedLetter : Letter
{
// .. ReceviedLetter properties
}
public class MyDbContext : DbContext
{
public DbSet<Folder> Folders {get; set;}
public DbSet<Letter> Letters {get; set;}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// Folder <-> Letters
modelBuilder.Entity<Letter>()
.HasRequired(t => t.Folder)
.WithMany(f => f.Letters)
.HasForeignKey(t => t.FolderId)
.WillCascadeOnDelete(true);
}
}
public IRepository<T> where T: BaseEntityObject
{
void Add(T entity);
void Remove(T entity);
void Attach(T entity);
void MarkAsModified(T entity);
List<T> Get();
T FindById(int id);
int SaveChanges();
void Dispose();
}
public abstract class EFRepository<T> : IRepository<T>
{
protected readonly DbContext Context;
public EFRepository(DbContext context)
{
Context = context;
}
public abstract List<T> Get();
public void Add(T item)
{
Context.Set<T>().Add(item);
}
public void Remove(T item)
{
Context.Set<T>().Remove(item);
}
public void Attach(T item)
{
Context.Set<T>().Attach(item);
MarkAsModified(item);
}
public void MarkAsModified(T item)
{
Context.Entry(item).EntityState = EntityState.Modified;
}
public void Update(T item)
{
Context.Entry(item).State = EntityState.Modified;
}
public void Dispose()
{
Context.Dispose();
}
public int SaveChanges()
{
return Context.SaveChanges();
}
public T FindById(int id)
{
return Context.Set<T>().Find(id);
}
}
public LettersRepository : EFRepository<Letter>
{
public LettersRepository(DbContext context) : base(context) {}
// Override for case includes will be needed in future
public override List<T> Get()
{
return Context.Set<T>().ToList();
}
}
public FoldersRepository : EFRepository<Folder>
{
public FoldersRepository(DbContext context) : base(context) {}
public override List<T> Get()
{
return Context.Set<T>().Include("Letters").ToList();
}
}
public interface IUnitOfWork
{
void Commit();
}
public class EFUnitOfWork : IUnitOfWork
{
private readonly DbContext _context;
public IRepository<Folder> foldersRepository;
public IRepository<Letters> lettersRepository;
public class EFUnitOfWork(DbContext context, IRepository<Folder> folders, IRepository<Letter> letters)
{
_context = context;
_lettersRepository = letters;
_foldersRepository = folders;
}
public void Commit()
{
_context.SaveChanges();
}
public void Dispose()
{
_context.Dispose();
}
}
public class DataService : IDataService
{
private Func<Owned<Folder>> _unitOfWorkFactory;
public DataService(Func<Owned<IUnitOfWork>> unitOfWorkFactory)
{
_unitOfWorkFactory= unitOfWorkFactory;
}
public void SaveLetterInFolder (Letter letter)
{
using (var unitOfWork = unitOfWorkFactory()
{
unitOfWork.lettersRepository.Add(letter);
unitOfWork.Commit();
}
}
public void RemoveLetterFromFolder (int letterId)
{
using (var unitOfWork = unitOfWorkFactory()
{
var removed = new OutgoingLetter {Id = letterId}
unitOfWork.lettersRepository.Attach(removed);
unitOfWork.lettersRepository.Remove(removed);
unitOfWork.Commit();
}
}
public List<Letter> GetAllLetters (int folderId)
{
using (var unitOfWork = unitOfWorkFactory()
{
return unitOfWork.lettersRepository.Find(folderId).Letters;
}
}
}
Registrations
via dependency injection (Autofac):
UnitOfWork
is registered as perDependency
DbContext
is registered as perLifetimeScope
Repositories
are registered as perLifetimeScope