设置
我正在使用 the almighty SimpleInjector3 连接的 .NET4.0 上运行 Web 应用程序.我正在使用 Command-/QueryHandler architecture described here我在为命令处理程序配置依赖项时遇到问题。
示例代码
这是类结构的分解:
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<>));
这对于像这样的非通用记录器非常有效:
class WorkingLogger : ICommandLogger<SomeCommand> { /* ... */ }
问题
现在我有一组实现标记接口(interface)的命令,这样我就可以为所有这些使用一个记录器——但这不会被 SimpleInjector 拾取:
class NotWorkingLogger<T> : ICommandLogger<T>
where T : IMarkerInterface { /* ... */ }
我知道这不应该是差异问题,但我已经尝试使用 variance extensions只是为了确定但无济于事。
有没有办法配置这个场景?
最佳答案
您只需添加 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);
关于c# - 使用 Simple Injector 将开放通用类型注册为回退,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32143320/