The Setup
I'm running a web application on .NET4.0 that is wired up using the almighty SimpleInjector3. I'm using the Command-/QueryHandler architecture described here and I have an issue with configuring a dependency for a command handler.
Sample Code
Here is a breakdown of the class structure:
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
}
}
Decorator:
/// <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);
}
}
In my CompositionRoot
I configure it like this:
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<>));
This works very well for non-generic loggers like this one:
class WorkingLogger : ICommandLogger<SomeCommand> { /* ... */ }
The Problem
Now I have a set of commands that implement a marker interface so that I can use one single logger for all of them - but this won't be picked up by the SimpleInjector:
class NotWorkingLogger<T> : ICommandLogger<T>
where T : IMarkerInterface { /* ... */ }
I'm aware that this shouldn't be a variance issue but I've tried using the variance extensions just to be sure but to no avail.
Is there a way to configure this scenario?