似乎您正在扩展方法中实现用例。我认为这样做比创建普通类没有任何好处。因此,不要使用扩展方法,只需将此方法设为非静态,将其包装在非静态类中,并通过构造函数注入依赖项。
这可能看起来像这样:
public class CalculateProductPriceUseCase
{
private ICalculateProductPriceService _calculatePriceService;
private IUnitOfWork _unitOfWork;
public CalculateProductPriceUseCase(
ICalculateProductPriceService calculatePriceService,
IUnitOfWork unitOfWork)
{
_calculatePriceService = _calculatePriceService;
_unitOfWork = unitOfWork;
}
public void Handle(Product product)
{
product.Price = _calculatePriceService.Calculate();
_unitOfWork.Commit();
}
}
然而,这个解决方案仍然困扰我的是Commit
电话。为什么用例本身必须调用commit。这对我来说似乎是一个基础设施,很容易忘记实现它。特别是因为该类不创建 unitOfWork 本身,而是从外部获取它。
相反,您可以将此用例包装在为您执行此操作的装饰器中,但是...如果您这样做,则需要添加适当的抽象,以便可以将所有用例包装在此类装饰器中。它可能看起来像这样:
public class CalculateProductPrice
{
public int ProductId { get; set; }
}
public class CalculateProductPriceUseCaseHandler
: IUseCase<CalculateProductPrice>
{
private ICalculateProductPriceService _calculatePriceService;
private IUnitOfWork _unitOfWork;
public CalculateProductPriceUseCaseHandler(
ICalculateProductPriceService calculatePriceService,
IUnitOfWork unitOfWork)
{
_calculatePriceService = _calculatePriceService;
_unitOfWork = unitOfWork;
}
public void Handle(CalculateProductPrice useCase)
{
var product = _unitOfWork.Products.GetById(useCase.ProductId);
product.Price = _calculatePriceService.Calculate();
}
}
消费者现在可以依赖一个IUseCase<CalculateProductPrice>
,你可以给他们一个CalculateProductPriceUseCaseHandler
实例,或者将该实例包装在一个装饰器中。这是此类装饰器的示例:
public class TransactionUseCaseDecorator<T> : IUseCase<T>
{
private IUnitOfWork _unitOfWork;
private IUseCase<T> _decoratedInstance;
public TransactionUseCaseDecorator(IUnitOfWork unitOfWork,
IUseCase<T> decoratedInstance)
{
_unitOfWork = unitOfWork;
_decoratedInstance = decoratedInstance;
}
public void Handle(T useCase)
{
// Example: start a new transaction scope
// (or sql transaction or what ever)
using (new TransactionScope())
{
_decoratedInstance.Handle(useCase);
// Commit the unit of work.
_unitOfWork.Commit();
}
}
}
现在你有了一个可以包裹任何IUseCase<T>
实现的通用装饰器。