I have a generic interface that is implemented by a more than one concrete class. For example:
public interface IMyInterface<T> {}
internal class Impl1 : IMyInterface<int> {}
internal class Impl2 : IMyInterface<float> {}
I want to automatically register all implementations of IMyInterface<T> so that I can resolve a specific implementation supported for type T (in this case, either int or float). For example:
class TheConsumer
{
// `impl` should resolve to `Impl1`
public TheConsumer(IMyInterface<int> impl) {}
}
From what I can gather from this github issue and the documentation, there seems to be two mechanisms to do this:
var builder = new ContainerBuilder();
// Mechanism 1
builder.RegisterAssemblyOpenGenericTypes(typeof(Startup).Assembly)
.AssignableTo(typeof(IMyInterface<>))
.AsImplementedInterfaces();
// Mechanism 2
builder.RegisterAssemblyTypes(typeof(Startup).Assembly)
.AsClosedTypesOf(typeof(IMyInterface<>))
.AsImplementedInterfaces();
I've only managed to test the 2nd mechanism shown above. The first one I am speculating is the same; but it may not be. Overall I'm just really confused about how "generics" are handled in Autofac. The docs are also missing any mention of RegisterAssemblyOpenGenericTypes, which doesn't help. So here are my questions:
- What is the functional difference between the two versions above?
- In what case would you choose one or the other?
- What is an "open" and "closed" generic (terminology from the Autofac documentation)?