我使用简单的喷油器来管理我的注入依赖的寿命(在这种情况下UnitOfWork
),和我一样有一个单独的装饰,而不是我的服务或命令处理程序保存和处理后,看起来很高兴的样子,写业务时,代码容易得多逻辑层(按照所概述的架构这篇博客 )。
以上是通过使用简单的进样器MVC NuGet包可以正常使用(和非常容易)和组合物根容器的结构在以下代码中,如果在图中存在多于一个的依赖性相同的实例在所有注射 - 完美的实体框架模型上下文。
private static void InitializeContainer(Container container)
{
container.RegisterPerWebRequest<IUnitOfWork, UnitOfWork>();
// register all other interfaces with:
// container.Register<Interface, Implementation>();
}
我现在需要运行一些后台线程,并从简单的喷油器了解上线文档,该命令可以如下代理:
public sealed class TransactionCommandHandlerDecorator<TCommand>
: ICommandHandler<TCommand>
{
private readonly ICommandHandler<TCommand> handlerToCall;
private readonly IUnitOfWork unitOfWork;
public TransactionCommandHandlerDecorator(
IUnitOfWork unitOfWork,
ICommandHandler<TCommand> decorated)
{
this.handlerToCall = decorated;
this.unitOfWork = unitOfWork;
}
public void Handle(TCommand command)
{
this.handlerToCall.Handle(command);
unitOfWork.Save();
}
}
ThreadedCommandHandlerProxy:
public class ThreadedCommandHandlerProxy<TCommand>
: ICommandHandler<TCommand>
{
Func<ICommandHandler<TCommand>> instanceCreator;
public ThreadedCommandHandlerProxy(
Func<ICommandHandler<TCommand>> creator)
{
this.instanceCreator = creator;
}
public void Handle(TCommand command)
{
Task.Factory.StartNew(() =>
{
var handler = this.instanceCreator();
handler.Handle(command);
});
}
}
然而,从这个线程样本文档,我可以看到工厂的使用,如果我介绍的工厂,以我的命令和服务层的东西会感到困惑和矛盾,因为我将有不同的服务不同的储蓄方法(一个容器处理保存,其它实例化的工厂内服务句柄保存和处置) - 你可以看到服务代码框架如何简单明了的是,没有任何工厂:
public class BusinessUnitCommandHandlers :
ICommandHandler<AddBusinessUnitCommand>,
ICommandHandler<DeleteBusinessUnitCommand>
{
private IBusinessUnitService businessUnitService;
private IInvoiceService invoiceService;
public BusinessUnitCommandHandlers(
IBusinessUnitService businessUnitService,
IInvoiceService invoiceService)
{
this.businessUnitService = businessUnitService;
this.invoiceService = invoiceService;
}
public void Handle(AddBusinessUnitCommand command)
{
businessUnitService.AddCompany(command.name);
}
public void Handle(DeleteBusinessUnitCommand command)
{
invoiceService.DeleteAllInvoicesForCompany(command.ID);
businessUnitService.DeleteCompany(command.ID);
}
}
public class BusinessUnitService : IBusinessUnitService
{
private readonly IUnitOfWork unitOfWork;
private readonly ILogger logger;
public BusinessUnitService(IUnitOfWork unitOfWork,
ILogger logger)
{
this.unitOfWork = unitOfWork;
this.logger = logger;
}
void IBusinessUnitService.AddCompany(string name)
{
// snip... let container call IUnitOfWork.Save()
}
void IBusinessUnitService.DeleteCompany(int ID)
{
// snip... let container call IUnitOfWork.Save()
}
}
public class InvoiceService : IInvoiceService
{
private readonly IUnitOfWork unitOfWork;
private readonly ILogger logger;
public BusinessUnitService(IUnitOfWork unitOfWork,
ILogger logger)
{
this.unitOfWork = unitOfWork;
this.logger = logger;
}
void IInvoiceService.DeleteAllInvoicesForCompany(int ID)
{
// snip... let container call IUnitOfWork.Save()
}
}
通过以上我的问题开始形成,我从理解上的ASP .NET PerWebRequest寿命文件 ,下面的代码被用于:
public T GetInstance()
{
var context = HttpContext.Current;
if (context == null)
{
// No HttpContext: Let's create a transient object.
return this.instanceCreator();
}
object key = this.GetType();
T instance = (T)context.Items[key];
if (instance == null)
{
context.Items[key] = instance = this.instanceCreator();
}
return instance;
}
上述工作正常,每次HTTP请求将会有一个有效的HttpContext.Current
,但是如果我旋了一个新的线程与ThreadedCommandHandlerProxy
它会创建一个新的线程和HttpContext
将是线程中不再存在。
由于HttpContext
将是对每个后续调用空,对象的所有实例注入的服务构造将是新的,独特的,相反,每Web请求正常的HTTP,而对象正确共享作为所有服务相同的实例。
所以总结到上述问题:
我将如何去获取物体构造和无论从HTTP请求或通过一个新的线程创建的常见项目注入?
有没有一种具有任何特殊考虑UnitOfWork
命令处理程序代理内由一个线程管理? 如何确保它被保存和设置在处理程序执行之后的?
如果我们有命令处理程序/服务层中的问题,并没有要保存UnitOfWork
,我们会简单地抛出一个异常? 如果是的话,是有可能抓住这个在全球层面,还是我们需要从抓内每个请求例外try
- catch
在处理装饰或代理?
谢谢,
克里斯