0

我正在尝试了解工作单元模式。但是,我很难找到一个不太简单或不太复杂的示例。所以决定试着从我读过的东西中写一些我自己的东西。我想知道我所做的是否可以接受。我正在尝试将图层解耦。我创建 DatabaseManager 的原因是为了避免将上下文发送到其他层。最后,这将是具有中间层(业务)的 MVC 应用程序的 DAL

感谢您的输入。

代码:

public interface IDatabaseFactory : IDisposable
    {
        ObjectContext Get();
    }

    public class DatabaseFactory : Disposable, IDatabaseFactory
    {
        private ObjectContext _dataContext;

        #region IDatabaseFactory Members

        public ObjectContext Get()
        {
            return _dataContext ?? (_dataContext = (new MyMemberDatabase()));
        }

        #endregion

        protected override void DisposeCore()
        {
            if (_dataContext != null)
                _dataContext.Dispose();
        }
    }

    public static class DatabaseManager
    {
        private static readonly Dictionary<Guid, ObjectContext> ContextLists = new Dictionary<Guid, ObjectContext>();

        public static ObjectContext GetContext(Guid id)
        {
            if (!ContextLists.ContainsKey(id))
            {
                Guid newContextID = id;
                ContextLists.Add(newContextID, new DatabaseFactory().Get());
            }

            return ContextLists[id];
        }

        public static void RemoveContext(Guid id)
        {
            if (ContextLists[id] != null)

                ContextLists.Remove(id);
        }
    }

    public class Disposable : IDisposable
    {
        private bool _isDisposed;

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

        ~Disposable()
        {
            Dispose(false);
        }

        private void Dispose(bool disposing)
        {
            if (!_isDisposed && disposing)
            {
                DisposeCore();
            }

            _isDisposed = true;
        }

        protected virtual void DisposeCore()
        {
        }
    }

    public interface IUnitOfWork : IDisposable
    {
        Guid ContextID { get; }
        void Commit();
    }

    public class UnitOfWork : IUnitOfWork
    {
        private readonly Guid _contextID;

        public UnitOfWork()
        {
            _contextID = new Guid();
            _contextID = Guid.NewGuid();
        }

        #region IUnitOfWork Members

        public Guid ContextID
        {
            get { return _contextID; }
        }

        public void Commit()
        {
            DatabaseManager.GetContext(_contextID).SaveChanges();
        }

        public void Dispose()
        {
            DatabaseManager.RemoveContext(_contextID);
        }

        #endregion
    }


    public abstract class RepositoryBase<T> where T : class
    {
        private readonly IUnitOfWork _unitOfWork;
        private ObjectContext _context;
        private IObjectSet<T> _objectSet;

        private ObjectContext Context
        {
            get { return _context ?? (_context = DatabaseManager.GetContext(_unitOfWork.ContextID)); }
        }

        protected IObjectSet<T> ObjectSet
        {
            get { return _objectSet ?? (_objectSet = Context.CreateObjectSet<T>()); }
        }

        protected RepositoryBase(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }

    }
class MemberRepository : RepositoryBase<Member>
    {
        public MemberRepository(IUnitOfWork unitOfWork) : base(unitOfWork)
        {
        }


        public virtual void Add(Member entity)
        {
            ObjectSet.AddObject(entity);
        }

        public virtual void Delete(Member entity)
        {
            ObjectSet.DeleteObject(entity);
        }

        public virtual IEnumerable<Member> GetAll()
        {
            return ObjectSet.AsEnumerable();
        }

    }

编辑:新代码

public  interface IMemberRepository : IRepository
{
    void Add(Member entity);
    void Delete(Member entity);
    IEnumerable<Member> GetAll();
}
public interface IRepository
{
    IUnitOfWork UnitOfWork { get; }
}
public interface IUnitOfWork : IDisposable
{
    void Commit();
}

public class DatabaseFactory : Disposable, IDisposable
{
    private ObjectContext _dataContext;

    public ObjectContext Get()
    {
        return _dataContext ?? (_dataContext = (new MyMemberDatabase()));
    }

    protected override void DisposeCore()
    {
        if (_dataContext != null)
            _dataContext.Dispose();
    }
}
public static class DatabaseManager
{
    private static readonly Dictionary<Guid, ObjectContext> ContextLists = new Dictionary<Guid, ObjectContext>();

    public static ObjectContext GetContext(Guid id)
    {
        if (!ContextLists.ContainsKey(id))
        {
            Guid newContextID = id;
            ContextLists.Add(newContextID, new DatabaseFactory().Get());
        }
        return ContextLists[id];
    }

    public static void RemoveContext(Guid id)
    {
        if (ContextLists[id] != null)
            ContextLists.Remove(id);
    }
}
public class Disposable : IDisposable
{
    private bool _isDisposed;

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

    ~Disposable()
    {
        Dispose(false);
    }

    private void Dispose(bool disposing)
    {
        if (!_isDisposed && disposing)
        {
            DisposeCore();
        }

        _isDisposed = true;
    }

    protected virtual void DisposeCore()
    {
    }
}
public class UnitOfWork : IUnitOfWork
{
    private readonly Guid _contextID;

    public UnitOfWork()
    {
        _contextID = new Guid();
        _contextID = Guid.NewGuid();
    }

    #region IUnitOfWork Members

    internal Guid ContextID
    {
        get { return _contextID; }
    }

    public void Commit()
    {
        DatabaseManager.GetContext(_contextID).SaveChanges();
    }

    public void Dispose()
    {
        DatabaseManager.RemoveContext(_contextID);
    }

    #endregion
}
public abstract class RepositoryBase<T> : IRepository where T : class
{
    private readonly UnitOfWork _unitOfWork;
    private ObjectContext _context;
    private IObjectSet<T> _objectSet;

    public IUnitOfWork UnitOfWork
    {
        get { return _unitOfWork; }
    }

    private ObjectContext Context
    {
        get { return _context ?? (_context = DatabaseManager.GetContext(_unitOfWork.ContextID)); }
    }

    protected IObjectSet<T> ObjectSet
    {
        get { return _objectSet ?? (_objectSet = Context.CreateObjectSet<T>()); }
    }

    protected RepositoryBase(IUnitOfWork unitOfWork)
    {
        _unitOfWork = (UnitOfWork)unitOfWork;
    }

    protected RepositoryBase()
    {
        _unitOfWork = new UnitOfWork();
    }
}
public class MemberRepository :  RepositoryBase<Member> ,IMemberRepository
{
    public MemberRepository(IUnitOfWork unitOfWork) : base(unitOfWork)
    {
    }

    public MemberRepository():base()
    {
    }

    public virtual void Add(Member entity)
    {
        ObjectSet.AddObject(entity);
    }

    public virtual void Delete(Member entity)
    {
        ObjectSet.DeleteObject(entity);
    }

    public virtual IEnumerable<Member> GetAll()
    {
        return ObjectSet.AsEnumerable();
    }
}
4

1 回答 1

2

我认为您的工作单元实施很好,应该可以工作。

在这里,您还有其他可能的实现:

// Interface used by upper layer
public interface IUnitOfWork : IDisposable
{
    void Commit();
}

// EF dependent unit of work
public class EFUnitOfWork : IUnitOfWork
{
    private readonly ObjectContext _context = new ObjectContext(...);

    internal ObjectContext Context
    {
        get { return _context; }
    }

    ...
}

// EF dependent repository - upper layer uses interface
public abstract class EFRepositoryBase<T> : IRepository<T> where T : class
{
    private readonly ObjectContext _context;
    private IObjectSet<T> _objectSet;

    // yes unit of work and repository is tightly coupled because they both have
    // to work with EF
    public EFRepositoryBase(EFUnitOfWork unitOfWork)
    {
        _context = unitOfWork.Context;
    }

    ...
}

如果您将工作单元和存储库实现放在单独的程序集中,那就足够了。使用ObjectContext将是 EF DAL 程序集的内部实现,上层将不依赖于 EF 及其程序集。

这可以通过硝化 DALFactory 进一步改善。Factory 将负责实例化、处理ObjectContext和创建 unitOfWork 和存储库。它将消除 UoW 和存储库之间的紧密耦合。

我也在使用这个实现,它将 UoW 和抽象工厂结合起来用于存储库,但是自从我写了那个答案后,我已经对其进行了一些修改。现在我的实现没有每个存储库的属性。相反,它使用通用方法返回请求的实体类型的存储库。存储库内部存储在字典中。但是这个实现不是很干净UoW。

另一个流行的实现是:

// Interface used by upper layer
public interface IUnitOfWork : IDisposable
{
    void SaveChanges();
}

public class UnitOfWork : ObjectContext, IUnitOfWork
{

}
于 2011-02-28T13:20:36.687 回答