lundi 9 janvier 2017

Rate my implementation of Unif Of Work with Repository pattern and EF Core

I wanted to try something new in regards of design patterns. I have ended up with Unit Of Work with Repository and EF Core. So I just want to display my "real world" solution and maybe hear what you guys think..? Room for improvement or have I maybe overlooked a potential fatal exception? I used this guide with a few changes http://ift.tt/2j9hKrF

My project is a server/client where the server exposes a MVC WEB API, to be used by multiple winform clients on the same local network.

I have my service classes that handles each area of the system. In this example my MachineService is used. Each service class uses an abstract BaseClass that holds the UnitOfWork instance. Each of the service classes can use each other, but the instance of the UnitOfWork must be handed around. So the same instance of UnitOfWork is used for the whole transaction no matter how many service classes is in use.

Here is the code: Repository

public class Repository<T> : IRepository<T>, IDisposable where T : class
{
    protected CompleteDbContext dbContext;

    protected DbSet<T> dbSet;

    public Repository(CompleteDbContext context)
    {
        dbContext = context;
        dbSet = context.Set<T>();
    }

    public virtual IEnumerable<T> DataSet { get { return dbSet; } }

    public virtual void Create(T entity)
    {
        dbSet.Add(entity);
    }

    public virtual T GetById(Guid id)
    {
        return dbSet.Find(id);
    }

    public virtual void Update(T entity)
    {
        dbContext.Entry(entity).State = EntityState.Modified;
    }

    public virtual void Delete(T entity)
    {
        dbSet.Remove(entity);
    }

    public List<T> GetAllList()
    {
        return dbSet.ToList();
    }

    public virtual IQueryable<T> Query(Expression<Func<T, bool>> filter = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null)
    {
        IQueryable<T> query = dbSet;

        if (filter != null)
            query = query.Where(filter);

        if (orderBy != null)
            query = orderBy(query);

        return query;
    }

    private bool disposed = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                dbContext.Dispose();
            }
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

IRepository

public interface IRepository<T> : IDisposable where T : class
{
    IEnumerable<T> DataSet { get; }

    void Create(T entity);

    T GetById(Guid id);

    void Update(T entity);

    void Delete(T entity);

    List<T> GetAllList();

    IQueryable<T> Query(Expression<Func<T, bool>> filter = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null);
}

The base class for the service classes: BaseClass

public abstract class BaseService
{
    private UnitOfWork _unitOfWork;

    public UnitOfWork unitOfWork
    {
        get
        {
            if (this._unitOfWork == null)
            {
                _unitOfWork = new UnitOfWork();
            }
            return _unitOfWork;
        }
        set { _unitOfWork = value; }
    }

    public BaseService(UnitOfWork unitOfWork)
    {
        this.unitOfWork = unitOfWork;
    }

    public bool Commit()
    {
        try
        {
            unitOfWork.Commit();
            return true;
        }
        catch (Exception ex)
        {
            unitOfWork.Rollback();
            // log error
            return false;
        }
        finally
        {
            unitOfWork.Dispose();
        }
    }
}

And then the finally the MachineService that makes use of UnitOfWork.

    public class MachineService : BaseService, IMachineService
    {
        private MachineEventService _machineEvent;

        private MachineEventService machineEventService
        {
            get {
            if (_machineEvent == null)
                _machineEvent = new MachineEventService(unitOfWork);
            else
                return _machineEvent;
            }
            set { _machineEvent = value; }
        }

        public MachineService() : base(new UnitOfWork()) { }

        public MachineService(UnitOfWork unitOfWork) : base(unitOfWork) { }

        public Machine GetMachine(Guid machineId)
        {
            var machine = unitOfWork.MachineRepository.GetById(machineId);
            if (machine.CurrentEventId.HasValue)
            {
                machine.CurrentEvent =  machineEventService.GetEvent(machine.CurrentEventId.Value);
            }
            return machine;
        }
    }

Aucun commentaire:

Enregistrer un commentaire