gpt4 book ai didi

repository - 在业务层中使用工作单元/存储库的正确方法是什么?

转载 作者:行者123 更新时间:2023-12-04 16:01:47 26 4
gpt4 key购买 nike

使用工作单元/存储库模式构建了一个小型应用程序后,我正在努力理解如何在我的业务层中正确使用它。我的应用程序有一个数据访问层,它可以是 NHibernate 或 Entity Framework 。我可以轻松地在这些之间切换。

我有许多存储库,例如客户、订单等。我的工作单元将是 ISession 或对象上下文,具体取决于我想用哪个 DAL 进行测试。

我的业务层包含一个业务方法 - CreateOrder()。我很难理解的是,我应该在业务层的哪个位置初始化我的工作单元和我的存储库。

专注于 Nhibernate,我的 DAL 看起来像:

public class NHibernateDAL : IUnitOfWork
{
log4net.ILog log = log4net.LogManager.GetLogger(typeof(NHibernateDAL));
ISession context;

public NHibernateDAL()
{
context = SessionProvider.OpenSession();
this.Context.BeginTransaction();
CurrentSessionContext.Bind(context);
}

public ISession Context
{
get { return context; }
}

public void Commit()
{
this.Context.Transaction.Commit();
context.Close();
}

public void Dispose()
{
ISession session = CurrentSessionContext.Unbind(SessionProvider.SessionFactory);
session.Close();
}
}

在我的业务层中,我想知道我应该在哪里声明我的工作单元和存储库。它们是在类级别还是在 CreateOrder 方法中声明的?

例如:
public class BusinessLogic
{
UnitOfWork _unitOfWork = new UnitOfWork(NHibernateDAL);
NhRepository<Order> _orderRepository = new NhRepository<Order>(_unitOfWork);
NhRepository<Customer> _customerRepository = new NhRepository<Customer>(_unitOfWork);
....

public void CreateOrder(.....)
{
Order order = new Order();
_orderRepository.Add(order);

_unitOfWork.Commit();
}
}

上述代码仅在第一次调用 CreateOrder() 方法时有效,但不适用于后续调用,因为 session 已关闭。我尝试在提交事务后删除 'context.Close()' 调用,但这也失败了。尽管上述方法不起作用,但在我看来,使用此范围声明我的存储库和工作单元似乎更正确。

但是,如果我按如下方式实现它,它可以正常工作,但是在方法本身的范围内声明存储库和工作单元似乎很不自然。如果我有大量的业务方法,那么我会在所有地方声明存储库和工作单元:
public class BusinessLogic
{
public void CreateOrder(.....)
{
UnitOfWork _unitOfWork = new UnitOfWork(NHibernateDAL);
var _orderRepository = new NhRepository<Order>(_unitOfWork);

NhRepository<Customer> _customerRepository = null;
Order order = new Order();
_orderRepository.Add(order);

_unitOfWork.Commit();
}
}

如果我要使用类级别声明来实现这一点,那么我想我需要一些方法来在 CreateOrder 方法开始时重新打开相同的工作单元。

在业务层中使用工作单元和存储库的正确方法是什么?

最佳答案

在我看来,您几乎已经掌握了。在我们的新服务器堆栈中,我有这样的设置:

WCF Service Layer  --> just returns results from my Business Layer

My business layer is called, creates a unitofwork, creates the respository
Calls the respository function
Uses AutoMapper to move returned results into a DTO

My repository gets the query results and populates a composite object.

看起来几乎就像你在那里得到的一样。尽管我们使用 Unity 来定位您所谓的业务层。 (我们只是称它为我们的函数处理器)

不过,我强烈建议您不要将 UnitOfWork 保留在类(class)级别。毕竟每个 descreet 函数都是一个工作单元。所以我的是这样的(为了保护无辜,名字已经改变了):
        using ( UnitOfWorkScope scope = new UnitOfWorkScope( TransactionMode.Default ) )
{
ProcessRepository repository = new ProcessRepository( );
CompositionResultSet result = repository.Get( key );
scope.Commit( );

MapData( );
return AutoMapper.Mapper.Map<ProcessSetDTO>( result );
}

我们还就何时执行 scope.Commit 进行了长时间的讨论,虽然查询不需要它,但它为应用层中的每个函数建立了一致的模式。顺便说一句,我们将 NCommon 用于我们的存储库/工作单元模式,并且不必将 UoW 传递给存储库。

关于repository - 在业务层中使用工作单元/存储库的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5580651/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com