我想让我的工作单元远离我的业务逻辑。
在 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 ();
}
更好的做法是在通用_unitOfWork.Commit()
而不是_unitOfWork.Rollback()
图层中调用Repository
或Service
吗?
我正在考虑通过向其中注入Repository
来改进通用IUnitOfWork
,同时添加一些额外的错误处理。
如果这不是一个好方法,有人可以给我一些改进的方向吗?注意:我确实希望保留repository pattern
,以防我们在几年内选择切换ORM
。
答案 0 :(得分:1)
管理存储库中的事务绝对不是执行它的标准方法,因为它消除了实现跨多个存储库(或在同一存储库上的多个操作)的业务逻辑的可能性,并且需要以原子方式执行。
我会尝试将事务管理保留在最有意义的最顶层,即如果您决定在不同的环境中托管应用程序,那么这不会影响您重用业务逻辑(包括事务管理)的能力例如。这似乎是您案例中的服务层;您还可以在域驱动设计中区分不同类型的服务,其中应用程序服务和域服务之间存在差异。 应用程序服务可能会编排多个域服务并处理事务管理和可能的工作单元。
希望这有点帮助。