通用存储库中的工作单元

本文关键字:工作 单元 存储 | 更新日期: 2024-10-20 04:33:08

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

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中调用_unitOfWork.Commit()_unitOfWork.Rollback()是否比在Service层中调用更好?

我想通过将IUnitOfWork注入到通用Repository中来改进它,同时在中添加一些额外的错误处理。

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

通用存储库中的工作单元

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

我会尽量将事务管理保持在最顶层,这是有意义的,也就是说,如果您决定在不同的环境中托管应用程序,这不会损害您重用业务逻辑(包括事务管理)的能力。在您的情况下,这似乎是服务层;您还可以在域驱动设计中区分不同类型的服务,其中应用程序服务域服务用程序服务可能会协调多个域服务

希望这能有所帮助。