This project is read-only.

Variance with non-collection registrations

Feb 22, 2015 at 9:54 AM
When registering a collection with the container the container will manage variance:
[Fact]
public void GetAllInstance_WithVariance_Succeeds()
{
    var container = new Container();
    container.RegisterManyForOpenGeneric(
        typeof(ICommandHandler<>),
        container.RegisterAll,
        typeof(ICommandHandler<>).Assembly);

    var result = container.GetAllInstances<ICommandHandler<DerivedFromStubCommand>>();

    Assert.IsType<StubCommandHandler>(result.Single());
}
The same thing does not happen with a single registration:
[Fact]
public void GetInstance_WithImplicitVariance_Fails()
{
    var container = new Container();
    container.Register<ICommandHandler<StubCommand>, StubCommandHandler>();

    Assert.Throws<ActivationException>(() => 
        container.GetInstance<ICommandHandler<DerivedFromStubCommand>>());
}
I have to manually register the variance for the derived command to be handled:
[Fact]
public void GetInstance_WithExplicitVariance_Succeeds()
{
    var container = new Container();
    container.Register<ICommandHandler<StubCommand>, StubCommandHandler>();
    container.Register<ICommandHandler<DerivedFromStubCommand>, StubCommandHandler>();

    var result = container.GetInstance<ICommandHandler<DerivedFromStubCommand>>();
}
Is there some way to get the container to handle the variance without an explicit registration for each derived command?
Feb 22, 2015 at 1:47 PM
Edited Feb 22, 2015 at 1:54 PM
The way to do this is to register a fallback implementation that can forward the command to an assignable implementation. A more detailed discussion with solutions can be found in this blog post. This post also describes why Simple Injector has no support for this. Especially take a look at "Scenario 2" in the blog post.
Marked as answer by qujck on 2/22/2015 at 7:34 AM
Feb 22, 2015 at 1:54 PM
Especially take a look at "Scenario 2" in the blog post.