我在.NET4.0上运行使用the almighty SimpleInjector3连接的Web应用程序。我使用Command-/QueryHandler architecture described here,我遇到了为命令处理程序配置依赖项的问题。
以下是课程结构的细分:
selectEmployee = selectEmployee.Replace(" ", "").Trim();
装饰:
interface ICommandHandler<T>
{
void Handle(T command);
}
enum LoggingState { Success, Failed }
interface ICommandLogger<T>
{
void Log(LoggingState state, T command);
}
class NullCommandLogger<T> : ICommandLogger<T>
{
void Log(LoggingState state, T command)
{
// Intentionally left blank
}
}
在我的/// <summary>
/// The logging command handler that gets wrapped around every
/// command handlers.
/// </summary>
class LoggingCommandHandlerDecorator<TCommand> : ICommandHandler<TCommand>
{
private readonly ICommandHandler<TCommand> decorated;
private readonly ICommandLogger<TCommand> logger;
public LoggingCommandHandlerDecorator(
ICommandHandler<TCommand> decorated,
ICommandLogger<TCommand> logger)
{
this.decorated = decorated;
this.logger = logger;
}
public void Handle(TCommand command)
{
try
{
this.decorated.Handle(command);
}
catch (Exception)
{
this.logger.Log(LoggingState.Failed, command);
throw;
}
this.logger.Log(LoggingState.Success, command);
}
}
中,我将其配置为:
CompositionRoot
这对于像这样的非通用记录器非常有效:
var assembly = /* Get the assembly where the handlers are located */
// Register all explicitly defined loggers
container.Register(typeof(ICommandLogger<>), assembly);
// Register null objects for everything else
container.RegisterConditional(
typeof(ICommandLogger<>),
typeof(NullCommandLogger<>),
ctx => !ctx.Handled);
// Wrap all command handlers with the logging
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(LoggingCommandHandlerDecorator<>));
现在我有一组实现标记接口的命令,以便我可以为所有这些命令使用一个记录器 - 但这不会被SimpleInjector选中:
class WorkingLogger : ICommandLogger<SomeCommand> { /* ... */ }
我知道这不应该是一个差异问题,但我尝试使用variance extensions只是为了确定但无济于事。
有没有办法配置这种情况?
答案 0 :(得分:1)
您只需要明确添加NotWorkingLogger<T>
的注册,如下所示:
container.Register(typeof(ICommandLogger<>), assembly);
// It's added between the two other registrations
container.RegisterConditional(
typeof(ICommandLogger<>),
typeof(NotWorkingLogger<>),
ctx => !ctx.Handled);
container.RegisterConditional(
typeof(ICommandLogger<>),
typeof(NullCommandLogger<>),
ctx => !ctx.Handled);