SimpleInjector IEnumerable<ISomeService<T>> With A Mixture Of Open & Closed Generics – Further investigation

Please note that as of Release 2.3 of SimpleInjector the features discussed in this and related articles are available out of the box with the new registration method RegisterAllOpenGeneric

This post is a follow on from previous posts here and here.

I’ve altered the test to return IEnumerable<ISomeService<T>> where T is an interface instead of a class.

    public interface IClass { }
    public interface IObserve<T> { }

    public class Class1 : IClass { }
    public class Class2 : IClass { }

    public class ObserveClass1 : IObserve<IClass> { }
    public class ObserveClass2 : IObserve<IClass> { }

    public class ObserveIObserve<TCommand> : IObserve<TCommand>
        where TCommand : IClass { }
    public class InjectionTestClass1
    {
        private readonly IEnumerable<IObserve<IClass>> _v;
        public InjectionTestClass1(IEnumerable<IObserve<IClass>> v) { _v = v; }
        public int HandlerCount { get { return _v.Count(); } }
    }

The rest of the code is as it was in the last posts, i.e. I have not investigated the different registration options of each Container.

What I expect to happen is each request for IEnumerable<IObserve<IClass>> will contain 3 classes: ObserveClass1, ObserveClass1 and ObserveIObserve

Results

Autofac

  1. Returns duplicate instances of closed generic types when asked for all implementations: ObserveClass2, ObserveClass1, ObserveClass2, ObserveClass1
  2. Fails with an exception when a request for a single implementation has multiple options

Ninject

  1. Returns a mixture of open and closed generics when asked for all implementations
  2. Returns an instance of an implementation when it has multiple options

StructureMap

  1. Returns duplicate instances of closed generic types when asked for all implementations: ObserveClass1, ObserveClass2, ObserveClass1, ObserveClass1
  2. Fails with an exception when a request for a single implementation has multiple options

Castle

  1. Returns a mixture of open and closed generics when asked for all implementations
  2. Returns an instance of an implementation when it has multiple options

SimpleInjector

  1. Returns a mixture of open and closed generics when asked for all implementations
  2. Fails with an exception when a request for a single implementation has multiple options

Summary

I don’t have the time or more importantly the expertise to investigate why each container behaves the way it does and if there is some other way of getting this to work. In the simple demonstration given here only Ninject and SimpleInjector are “correctly” resolving the request for multiple generic registrations.

2 out of 2 for SimpleInjector; 1 out of 2 for Ninject and Castle; 0 out of 2 for Autofac and StructureMap.