我正在使用Simple Injector来管理我注入的依赖项的生命周期(在这种情况下UnitOfWork),我很高兴有一个单独的装饰器而不是我的服务或命令处理程序,在编写业务逻辑时保存和处理使代码更容易图层(我遵循本博文中概述的架构).
通过在构造根容器的构造过程中使用Simple Injector MVC NuGet包和以下代码,上面的工作完美(并且非常容易),如果图中存在多个依赖项,则相同实例将全部注入 - 完美的实体框架模型上下文.
private static void InitializeContainer(Container container)
{
container.RegisterPerWebRequest<IUnitOfWork, UnitOfWork>();
// register all other interfaces with:
// container.Register<Interface, Implementation>();
}
Run Code Online (Sandbox Code Playgroud)
我现在需要运行一些后台线程并从Simple Injector 文档中了解可以代理命令的线程,如下所示:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
ThreadedCommandHandlerProxy:
public class ThreadedCommandHandlerProxy<TCommand>
: ICommandHandler<TCommand> …Run Code Online (Sandbox Code Playgroud) 我使用Simple Injector作为我的IoC容器.SimpleInjector使用这种简单的技术来处理Per Thread和Per Web Request的混合生活方式
container.RegisterPerWebRequest<IWebRepository, Repository>();
container.RegisterLifetimeScope<IThreadRepository, Repository>();
container.Register<IRepository>(container.GetInstance<Repository>());
// Register as hybrid PerWebRequest / PerLifetimeScope.
container.Register<Repository>(() =>
{
Repository repository;
if (HttpContext.Current != null)
repository = (Repository)container.GetInstance<IWebRepository>();
else
repository = (Repository)container.GetInstance<IThreadRepository>();
return repository;
});
Run Code Online (Sandbox Code Playgroud)
不幸的是(显然!),在我的UnitOfWork类的其他地方,当我使用Parallel.ForEach并尝试并行调用Repository类的多个实例时,这给了我一个问题,因为只有第一个线程在HttpContext中找到一个值.当前
using (TransactionScope scope = new TransactionScope())
{
Parallel.ForEach(new List<IRepository>() { _repository1, _repository2 ... },
(repository) =>
{
repository.Commit();
});
scope.Complete();
}
Run Code Online (Sandbox Code Playgroud)
既然我已经写完了这个问题,我可以看到我可能会要求不可能或者是愚蠢的东西......但到底是什么......这可以做到吗?单个请求/线程注册是否可用于多个内部线程?
c# multithreading dependency-injection task-parallel-library simple-injector
使用简单的喷油器与下面介绍的命令模式和这里所描述的查询模式.对于其中一个命令,我有2个处理程序实现.第一个是同步执行的"正常"实现:
public class SendEmailMessageHandler
: IHandleCommands<SendEmailMessageCommand>
{
public SendEmailMessageHandler(IProcessQueries queryProcessor
, ISendMail mailSender
, ICommandEntities entities
, IUnitOfWork unitOfWork
, ILogExceptions exceptionLogger)
{
// save constructor args to private readonly fields
}
public void Handle(SendEmailMessageCommand command)
{
var emailMessageEntity = GetThisFromQueryProcessor(command);
var mailMessage = ConvertEntityToMailMessage(emailMessageEntity);
_mailSender.Send(mailMessage);
emailMessageEntity.SentOnUtc = DateTime.UtcNow;
_entities.Update(emailMessageEntity);
_unitOfWork.SaveChanges();
}
}
Run Code Online (Sandbox Code Playgroud)
另一个就像一个命令装饰器,但显式包装前一个类在一个单独的线程中执行命令:
public class SendAsyncEmailMessageHandler
: IHandleCommands<SendEmailMessageCommand>
{
public SendAsyncEmailMessageHandler(ISendMail mailSender,
ILogExceptions exceptionLogger)
{
// save constructor args to private readonly fields
}
public …Run Code Online (Sandbox Code Playgroud) multithreading asynchronous dependency-injection entity-framework-4.1 simple-injector