繁体   English   中英

通用存储库中的工作单元

[英]Unit Of Work in Generic Repository

我想将工作单元从业务逻辑中移开。

Infrastructure.Data我有

NHibernateHelper

public class NHibernateHelper
{
    private ISessionFactory _sessionFactory;
    private readonly string _connectionString;

    public NHibernateHelper (string connectionString)
    {
        if (string.IsNullOrEmpty (connectionString))
            throw new HibernateConfigException ("ConnectionString in Web.config is not set.");

        _connectionString = connectionString;
    }

    public ISessionFactory SessionFactory {
        get {
            return _sessionFactory ?? (_sessionFactory = InitializeSessionFactory ());
        }
    }

    private ISessionFactory InitializeSessionFactory ()
    {
        return Fluently.Configure ()
            .Database (PostgreSQLConfiguration.Standard.ConnectionString (_connectionString).
                Dialect ("NHibernate.Dialect.PostgreSQL82Dialect"))
        // Use class mappings
            .Mappings (m => m.FluentMappings.AddFromAssembly (Assembly.GetExecutingAssembly ()))
        // Will Update and create tables if does not exist
            .ExposeConfiguration (cfg => new SchemaUpdate (cfg).Execute (true, true))
            .BuildSessionFactory ();
    }
}

UnitOfWork

public class UnitOfWork : IUnitOfWork
{
    private readonly ISessionFactory _sessionFactory;
    private readonly ITransaction _transaction;

    public ISession Session { get; private set; }

    public UnitOfWork (ISessionFactory sessionFactory)
    {
        _sessionFactory = sessionFactory;
        Session = _sessionFactory.OpenSession ();
        Session.FlushMode = FlushMode.Auto;
        _transaction = Session.BeginTransaction (IsolationLevel.ReadCommitted);
    }

    public void Commit ()
    {
        if (!_transaction.IsActive) {
            throw new InvalidOperationException ("Oops! We don't have an active transaction");
        }
        _transaction.Commit ();
    }

    public void Rollback ()
    {
        if (_transaction.IsActive) {
            _transaction.Rollback ();
        }
    }

    public void Dispose ()
    {
        if (Session.IsOpen) {
            Session.Close ();
            Session = null;
        }
    }
}

Repository

public class Repository<TEntity> : IReadWriteRepository<TEntity>
    where TEntity : class
{
    private readonly ISession _session;

    public Repository (ISession session)
    {
        _session = session;
    }

    #region IWriteRepository

    public bool Add (TEntity entity)
    {
        _session.Save (entity);
        return true;
    }

    public bool Add (System.Collections.Generic.IEnumerable<TEntity> entities)
    {
        foreach (TEntity entity in entities) {
            _session.Save (entity);
        }
        return true;
    }

    public bool Update (TEntity entity)
    {
        _session.Update (entity);
        return true;
    }

    public bool Update (System.Collections.Generic.IEnumerable<TEntity> entities)
    {
        foreach (TEntity entity in entities) {
            _session.Update (entity);
        }
        return true;
    }

    public bool Delete (TEntity entity)
    {
        _session.Delete (entity);
        return true;
    }

    public bool Delete (System.Collections.Generic.IEnumerable<TEntity> entities)
    {
        foreach (TEntity entity in entities) {
            _session.Delete (entity);
        }
        return true;
    }

    #endregion

    #region IReadRepository

    public System.Linq.IQueryable<TEntity> All ()
    {
        return _session.Query<TEntity> ();
    }

    public TEntity FindBy (System.Linq.Expressions.Expression<System.Func<TEntity, bool>> expression)
    {
        return FilterBy (expression).SingleOrDefault ();
    }

    public TEntity FindBy (object id)
    {
        return _session.Get<TEntity> (id);
    }

    public System.Linq.IQueryable<TEntity> FilterBy (System.Linq.Expressions.Expression<System.Func<TEntity, bool>> expression)
    {
        return All ().Where (expression).AsQueryable ();
    }

    #endregion
}

Intrastructure.DependencyInjectrion我有:

    public void RegisterServices (SimpleInjector.Container container)
    {

        var connectionSettings = ConfigurationManager.ConnectionStrings ["Connection"];

        container.RegisterPerWebRequest<ISessionFactory> (() => {
            NHibernateHelper objNHibernate = new NHibernateHelper (connectionSettings.ConnectionString);
            return objNHibernate.SessionFactory;
        });


        container.RegisterPerWebRequest<IUnitOfWork, UnitOfWork> ();

        container.RegisterPerWebRequest<ISession> (() => {

            UnitOfWork unitOfWork = (UnitOfWork)container.GetInstance<IUnitOfWork> ();
            return unitOfWork.Session;

        });

        container.RegisterOpenGeneric (typeof(IReadWriteRepository<>), typeof(Repository<>));

    }

然后在我的服务中,我将执行以下操作:

Web.UI.Services.CompanyService

    public void CreateNewCompany (Company company)
    {
        if (_companyRepository.Add (company))
            _unitOfWork.Commit ();
        else
            _unitOfWork.Rollback ();
    }

在能量Repository而不是在Service层中调用_unitOfWork.Commit()_unitOfWork.Rollback()是更好的做法吗?

我当时正在考虑通过IUnitOfWork注入IUnitOfWork来改进通用Repository ,同时IUnitOfWork添加一些其他错误处理。

如果这不是一个好的方法,有人可以给我一些指导以改进它吗? 注意:我确实想保留repository pattern ,以防我们选择在几年后切换ORM

在存储库中管理事务绝对不是实现此操作的标准方法,因为它消除了实现跨越多个存储库(或同一存储库上的多个操作)并需要原子执行的业务逻辑的可能性。

我会尝试将事务管理放在有意义的最顶层,即,例如,如果您决定将应用程序托管在不同的环境中,则这不会损害您重用业务逻辑(包括事务管理)的能力。 在您的情况下,这似乎是服务层; 您还可以区分不同类型的服务,如在域驱动设计中完成的那样,其中应用程序服务域服务之间存在差异。 应用程序服务可以协调多个域服务,并处理事务管理以及可能的工作单元管理。

希望这个对你有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM