这个模型是一个很好的管理模式UOW / Repository与NHibernate? [英] This model is a good management for the pattern UOW / Repository with NHibernate?

查看:158
本文介绍了这个模型是一个很好的管理模式UOW / Repository与NHibernate?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在StackOverflow和google上搜索我发现了许多不同的实现,但没有一个确实让我信服,每个都有一些小的缺陷阻止我使用它。所以我试着创建自己的版本,想知道你的想法。



基本上所有东西都是基于接口和UnitOfWork模式的使用而建立的风格实体框架,即使我使用NHibernate作为实现。



想要拥有绝对通用的接口,因此可以容纳EF NH我的UoW不暴露任何特定的两个存储库的概念,如会话或交易



这是用法:

 使用(IUnitOfWork uow =  new  NHUnitOfWork())
{
uow.StartOperation();
Class1 c1 = _uow.Class1Repo.Read< Class1>(idClasse1);
c1.Desc = 已编辑;
uow.Class1Repo.Update(c1);
}





当然可以使用依赖注入来避免新实例。



正如您所看到的,唯一的依赖是工作单元,而不是每个存储库,在可维护性和可扩展性方面具有优势



首先我为我的实体创建一个定义键的界面



> public  interface  IKeyedEntity< TKeyType> 其中 TKeyType: struct  
{
TKeyType Id {获得; set ; }
}







这些是接口:



  public   interface  IUnitOfWork:IDisposable { 
void StartOperation();
void SaveAll();
void DiscardChanges();
void OpenConnection();
void CloseConenction();

IClass1Repository Class1Repo { get ; }
// 此处所有其他存储库
}





此时我创建了我的通用存储库的基本接口,其中包含必须提供的所有操作(如果您希望可以创建通用存储库以实现明显划分从写入操作读取操作,以便您可以管理具有有限权限的存储库,而不会预见到更改的对象,但我不需要这种类型)





  public   interface  IRepoBase< TEntity,TKey> ; :IDisposable 
其中 TEntity: class ,IKeyedEntity< TKey>
其中 TKey: struct {
void Create(TEntity obj);
T读< T>(TKey id);
void 更新(TEntity obj);
void 删除(TEntity obj);
}







单个对象的所有剩余读取操作将按特定方式进行管理存储库



  public   interface  IClass1Repository:IDisposable,IRepoBase< Class1,int> 
{
IEnumerable< Class1>找到所有();
string GetFirstRecordDescription();
}





查询的所有条件和过滤器将使用更具体的方法直接进入存储库,为什么不使用IEnumerable IQueryable。通过这种方式,他们甚至没有链接到Linq



  public  < span class =code-keyword> class  NHUnitOfWork:IUnitOfWork {
private ITransaction _transaction;
private NHSessionFactory _nhHelper;
private ISession _session;
public IClass1Repository Class1Repo { get ; private set ; }

public NHUnitOfWork(NHSessionFactory nhHelper){
_nhHelper = nhHelper ?? new NHSessionFactory();
InitializeSession(); }

public NHUnitOfWork(){
_nhHelper = new NHSessionFactory ();
InitializeSession(); }

private void InitializeSession(){
if (_session == null
_session = _nhHelper.OpenSession();
Class1Repo = new Class1Repository( this ._ session);
// 此处所有其他存储库}

public void StartOperation(){
InitializeSession();
_transaction = _session.BeginTransaction(); }

public void SaveAll(){
if (_transaction!= null ){
_transaction.Commit();
_transaction = null ; }

public void DiscardChanges(){
合同。确保(_session.Transaction.IsActive == false );
if (_transaction!= null ){
_transaction.Rollback();
_transaction = null ;


public void OpenConnection(){
InitializeSession(); }

public void CloseConnection(){
if (_transaction!= null ){
_transaction.Dispose();
_transaction = null ; }

if (_session!= null ){
_session .Dispose();
_session = null ; }
}

// 这里的一次性模式
}





OpenConnection和CloseConenction隐藏了nhibernate会话,而StartOperation,SaveAll和DiscardChanges隐藏了原子操作的概念(事务)



BaseRepository的NH实现:



  public   class  NHRepoBase< TEntity,TKey> :IRepoBase< TEntity,TKey> 
其中 TEntity: class ,IKeyedEntity< TKey>
其中 TKey: struct

{
< span class =code-keyword> protected ISession _session;
public NHRepoBase(ISession session)
{_session = session; }

public void 创建(TEntity obj)
{_session .SaveOrUpdate(OBJ); }

public void 更新(TEntity obj)
{_session .Merge< T>(OBJ); }

public void 删除(TEntity obj)
{_session .Delete(OBJ); }

public T读< T>(TKey id)
{ return _session.Get< T>(id); }

私人 bool dispos = ;
受保护 虚拟 void Dispose ( bool disposing){
if (!this.disposed){
< span class =code-keyword> if
(disposing)
_session.Dispose();
}
.disposed = true ;
}
public void Dispose(){
Dispose(< span class =code-keyword> true );
GC.SuppressFinalize( this );
}
}





一个简单的特定存储库:



  class  Class1Repository:NHRepoBase< Class1,int> ;, IClass1Repository,IDisposable {
public Class1Repository(ISession session): base (session){}

public IEnumerable< Class1> FindAll()
{ return _session.QueryOver< Class1>()。List(); }

public string GetFirstRecordDescription()
{ return _session.QueryOver< Class1>()。选择(c = > c.Desc).SingleOrDefault< string> (); }
}





提前感谢您对我的实施的任何建议或反馈

解决方案

Searching on StackOverflow and google i find many and many different implementation but none of that really convinced me, each had some small defect that prevented me from using it. So I tried to create my own version and would like to know what you think.

Essentially everything is based on the use of interfaces and UnitOfWork pattern built in the style of the Entity Framework, even if I use NHibernate as implementation.

Wanting to have absolutely generic interfaces and can therefore accommodate both EF NH my UoW does not expose any of the specific concepts of the two repositories such as session or transaction

this is the usage:

using (IUnitOfWork uow = new NHUnitOfWork())
        {
            uow.StartOperation();
            Class1 c1 = _uow.Class1Repo.Read<Class1>(idClasse1);
            c1.Desc = "edited";
            uow.Class1Repo.Update(c1);
        }



of course the new instance can be avoided using dependency injection.

As you can see the only dependency is to Unit of Work, not to every repository, with advantage in terms of maintainability and scalability

first i create an interface for my entities which define the key

>public interface IKeyedEntity<TKeyType> where TKeyType : struct
    {
        TKeyType Id { get; set; }
    }




these are the interfaces:

public interface IUnitOfWork : IDisposable{
        void StartOperation();
        void SaveAll();
        void DiscardChanges();
        void OpenConnection();
        void CloseConenction();

        IClass1Repository Class1Repo { get; }
                // All other repository here
    }



At this point I created the basic interface of my generic repository containing all the operations that must be provided (if you want you can create generic repository for distinct divide the reading operations from those of writing so that you can manage the repository with limited permissions for objects that not foresee the change, but I had no need of this type)


public interface IRepoBase<TEntity, TKey> : IDisposable 
		where TEntity : class, IKeyedEntity<TKey>
		where TKey : struct {
            void Create(TEntity obj);
            T Read<T>(TKey id);
            void Update(TEntity obj);
            void Delete(TEntity obj);
    }




all the remaining read operations of individual objects will be managed in their specific repository

public interface IClass1Repository : IDisposable, IRepoBase<Class1, int>
{
    IEnumerable<Class1> FindAll();
    string GetFirstRecordDescription();
}



all the conditions and filters to queries will be made directly into the repository using more specific methods, why not use it IEnumerable IQueryable. In this way they are not even linked to Linq

public class NHUnitOfWork: IUnitOfWork{
        private ITransaction _transaction;
        private NHSessionFactory _nhHelper;
        private ISession _session;
        public IClass1Repository Class1Repo { get; private set; }

        public NHUnitOfWork(NHSessionFactory nhHelper)      {
            _nhHelper = nhHelper ?? new NHSessionFactory();
            InitializeSession();        }

        public NHUnitOfWork()       {
            _nhHelper = new NHSessionFactory();
            InitializeSession();        }

        private void InitializeSession()        {
            if (_session == null)
                   _session = _nhHelper.OpenSession();
            Class1Repo = new Class1Repository(this._session);
                        // All other repository here    }

        public void StartOperation()    {
            InitializeSession();
            _transaction = _session.BeginTransaction(); }

        public void SaveAll()   {
            if (_transaction != null)       {
                _transaction.Commit();
                _transaction = null;    }   }

        public void DiscardChanges()    {
            Contract.Ensures(_session.Transaction.IsActive == false);
            if (_transaction != null)       {
                _transaction.Rollback();
                _transaction = null;    }   }


        public void OpenConnection()        {
            InitializeSession();        }

        public void CloseConnection()   {
            if (_transaction != null)   {
                _transaction.Dispose();
                _transaction = null;    }

            if (_session != null)   {
                _session.Dispose();
                _session = null;    }
        }

        // Disposable pattern here
    }



OpenConnection and CloseConenction hide the nhibernate session, while StartOperation, SaveAll and DiscardChanges hide the concept of atomic operation (transaction)

NH implementation of BaseRepository:

public class NHRepoBase<TEntity, TKey> : IRepoBase<TEntity, TKey>
        where TEntity : class, IKeyedEntity<TKey>
        where TKey : struct

    {
        protected ISession _session;
        public NHRepoBase(ISession session)
        {_session = session;    }

        public void Create(TEntity obj)
        { _session.SaveOrUpdate(obj); }

        public void Update(TEntity obj)
        { _session.Merge<T>(obj); }

        public void Delete(TEntity obj)
        { _session.Delete(obj); }

        public T Read<T>(TKey id)
        { return _session.Get<T>(id); }

        private bool disposed = false;
        protected virtual void Dispose(bool disposing)  {
            if (!this.disposed){
                if (disposing)
                 _session.Dispose();
            }
            this.disposed = true;
        }
        public void Dispose()   {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    }



A simple specific repository:

class Class1Repository : NHRepoBase<Class1, int>, IClass1Repository, IDisposable {
        public Class1Repository(ISession session) : base(session) { }

        public IEnumerable<Class1> FindAll()
        { return _session.QueryOver<Class1>().List();    }

        public string GetFirstRecordDescription()
        { return _session.QueryOver<Class1>().Select(c => c.Desc).SingleOrDefault<string>(); }
    }



Thanks in advance for any suggestions or feedback on my implementation

解决方案

这篇关于这个模型是一个很好的管理模式UOW / Repository与NHibernate?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆