Is the following possible with Simple Injector 4?
var types = container.GetTypesToRegister(typeof(IFoo<>), assemblies);
container.RegisterCollection(typeof(IFoo<>), types);
with
public interface IFoo<T> where T : IBar { ... }
and
public interface IBar { ... }
and in the assembly similar types can be found like the following:
public class Foo : IFoo<FooBar> { ... }
where
public class FooBar : IBar { ... }
The container verifies this registration. But when I do
container.GetAllInstances<IFoo<IBar>>();
Then the result is empty. My intention is to inject the following:
IEnumerable<IFoo<IBar>> foos
which I expect to return all closed type implementations of IFoo<>
where the closed generic parameter is an implementation of IBar
.
Also another point is that whenever I want to write a unit test for the service that consumes IEnumerable<IFoo<IBar>>
, I'm trying to mock this with the following:
IEnumerable<IFoo<IBar>> collection = new[] { new Foo() };
new ConsumerService(collection);
Here the compiler has a hard time to convert the type Foo
to IFoo<IBar>
, which I think I understand (not sure..). But what I don't understand is that how Simple Injector would instantiate the types in the collection?
To be able to achieve what you want, you will have to make your IFoo<T>
interface variant.
The reason you get an empty list is because IFoo<IBar>
is not assignable from IFoo<FooBar>
. Try it out yourself: the C# compiler will not permit you to cast Foo
to IFoo<IBar>
.
To achieve this you will have to make IFoo<T>
covariant. In other words, you need to define the interface as follows:
public interface IFoo<out T> { }
After you done this, you'll see that Simple Injector automatically resolves all instances for you as you'd expect.
Whether however it is useful for you to have an out
type argument is a different question. One that I cannot answer, given the abstract description you gave.