使用Simple Injector将开放泛型类型注册为后备

时间:2015-08-21 14:46:59

标签: c# .net dependency-injection simple-injector

设置

我在.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只是为了确定但无济于事。

有没有办法配置这种情况?

1 个答案:

答案 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);