Best Practice of Repository and Unit of Work Pattern with Multiple DbContext

后端 未结 2 1638
北海茫月
北海茫月 2020-12-23 18:31

I plan to develop a web application using ASP.NET MVC with Entity Framework 6 (Code First / POCO). I also want to use generic Repository and Unit of Work Pattern in my appli

2条回答
  •  情歌与酒
    2020-12-23 18:39

    I would suggest you to create UnitOfWork pattern with a Constructor parameter to accept DbContext -

    public class UnitOfWork : IUnitOfWork
    {
        private readonly IDbContext _context;
    
        private bool _disposed;
        private Hashtable _repositories;
    
        public UnitOfWork(IDbContext context)
        {
            _context = context;
        }
    
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    
        public void Save()
        {
            _context.SaveChanges();
        }
    
        public virtual void Dispose(bool disposing)
        {
            if (!_disposed)
                if (disposing)
                    _context.Dispose();
    
            _disposed = true;
        }
    
        public IRepository Repository() where TEntity : class
        {
            if (_repositories == null)
                _repositories = new Hashtable();
    
            var type = typeof(TEntity).Name;
    
            if (_repositories.ContainsKey(type)) return (IRepository) _repositories[type];
    
            var repositoryType = typeof (Repository<>);
    
            var repositoryInstance =
                Activator.CreateInstance(repositoryType
                    .MakeGenericType(typeof (TEntity)), _context);
    
            _repositories.Add(type, repositoryInstance);
    
            return (IRepository) _repositories[type];
        }
    }
    

    where IDbContext is -

    public interface IDbContext
    {
        IDbSet Set() where T : class;
        int SaveChanges();
        void Dispose();
    }
    

    And the repository implementation would be -

     public class Repository : IRepository where TEntity : class
        {
            internal IDbContext Context;
            internal IDbSet DbSet;
    
            public Repository(IDbContext context)
            {
                Context = context;
                DbSet = context.Set();
            }
    
            public virtual TEntity FindById(object id)
            {
                return DbSet.Find(id);
            }
    
            public virtual void Update(TEntity entity)
            {
                DbSet.Attach(entity);
            }
            public virtual void Delete(object id)
            {
                var entity = DbSet.Find(id);
                var objectState = entity as IObjectState;
                if (objectState != null)
                    objectState.State = ObjectState.Deleted;
                Delete(entity);
            }
    
            public virtual void Delete(TEntity entity)
            {
                DbSet.Attach(entity);
                DbSet.Remove(entity);
            }
    
            public virtual void Insert(TEntity entity)
            {
                DbSet.Attach(entity);
            }
    
            public virtual List GetAll()
            {
                return DbSet.ToList();
            }
        }
    

    With this approach you can create a UnitOfWork for individual DBContext and you have specific logic to commit or rollback in UnitOfWork.

提交回复
热议问题