g18*_*18c 4 .net c# ioc-container inversion-of-control simple-injector
嗨我开始在我的所有项目中使用Simple Injector DI容器,并且想要一些关于如何适应的建议是我的要求的强大功能.
我有几个命令处理程序装饰器,它将包装命令:
public 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)
互斥装饰者:
public class TransactionCommandHandlerWithMutexDecorator<TCommand>
: ICommandHandler<TCommand>
{
private readonly ICommandHandler<TCommand> handlerToCall;
private readonly IUnitOfWork unitOfWork;
private static object Lock = new object();
public TransactionCommandHandlerWithMutexDecorator(
IUnitOfWork unitOfWork,
ICommandHandler<TCommand> decorated)
{
this.handlerToCall = decorated;
this.unitOfWork = unitOfWork;
}
public void Handle(TCommand command)
{
lock (Lock)
{
this.handlerToCall.Handle(command);
unitOfWork.Save();
}
}
}
Run Code Online (Sandbox Code Playgroud)
在某些情况下,只有以这种阻塞方式包装一些命令才有意义(通过使用TransactionCommandHandlerWithMutexDecorator),并允许其他人通过所有线程(使用TransactionCommandHandlerDecorator)进行精确访问,此外如果不在命令类型之间共享互斥锁,那将是很好的 - 我当前的代码,锁是静态的,将在所有类型之间共享.
所以我的问题:
1)如何将TransactionCommandHandlerWithMutexDecorator应用于特定的命令或命令,并使用TransactionCommandHandlerDecorator进行其余的操作 - 我会使用ExpressionBuilt事件吗?
2)我是否需要为每个我想要装饰的命令创建一个新类(以确保每个命令都有一个唯一的锁对象),或者是否有一些更好的方式(使用拦截)?
关于如何做到这一点的最佳方式的建议.
谢谢,
克里斯
使用我当前的代码,锁是静态的,并且将在所有类型之间共享.
这是不正确的.通用类型不共享静态成员.每一个TCommand都会有一个新的静态类型.换句话说,一个Decorator<int>将拥有与一个不同的static object Lock实例Decorator<string>.
如果你想要反过来,因此对所有命令都有1个单锁,这将有点困难.你基本上可以做三件事:
但同样,这不是你想要的.您想要的行为是默认情况下发生的行为,这与Simple Injector无关.这就是泛型在C#和.NET中的工作方式.
如何将TransactionCommandHandlerWithMutexDecorator应用于特定命令或命令,并使用TransactionCommandHandlerDecorator进行其余操作
这比你想象的要容易得多.有一个带有a的RegisterDecorator重载Predicate<T>,它允许你告诉何时装饰.这可能如下所示:
// Some helper methods
private static Type GetCommandType(Type handlerType)
{
return handlerType.GetGenericArguments()[0];
}
private static bool IsMutexCommand(Type commandType)
{
// Determine here is a class is a mutex command.
// Example:
return typeof(IMutexCommand).IsAssignableFrom(commandType);
}
// Decorator registration with predicates.
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(TransactionCommandHandlerWithMutexDecorator<>),
c => IsMutexCommand(GetCommandType(c.ServiceType)));
// Decorator registration with predicates.
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(TransactionCommandHandlerDecorator<>),
c => !IsMutexCommand(GetCommandType(c.ServiceType)));
Run Code Online (Sandbox Code Playgroud)
由于Simple Injector的所有功能都经过了RegisterDecorator高度优化.在正常情况下*谓词只会被调用一次.
*当多个线程同时同时请求相同的实例时,谓词被多次调用是可能的,但是在构建的表达式被缓存并且构建了委托之后,谓词将不再被调用.
| 归档时间: |
|
| 查看次数: |
1096 次 |
| 最近记录: |