Reputation: 512
I couldn't find a question talking about resolving a collection to base classes. I have the following pseudo test class which uses AutoFac to resolve handlers:
namespace Test {
interface IEventEmitter {}
interface IEventHandler {}
interface IEventHandler<in T> : IEventHandler where T: IEventEmitter {}
interface ISomeClass : IEventEmitter {}
class SomeClass : ISomeClass
{
// 2 handlers should be resolved here, not one!
public SomeClass(IEnumerable<IEventHandler> handlers) {}
}
class GenericEventHandler : IEventHandler {}
class DedicatedEventHandler : IEventHandler<ISomeClass> {}
[TestClass]
class TestClass
{
[TestMethod]
private void TestHandlers()
{
var builder = new ContainerBuilder();
// registered in order to resolve handlers
builder.RegisterType<SomeClass>().As<ISomeClass>();
builder.RegisterType<GenericEventHandler>().As<IEventHandler>();
builder.RegisterType<DedicatedEventHandler>().As<IEventHandler<ISomeClass>>();
var container = builder.Build();
using (var scope = container.BeginLifetimeScope())
{
var instanceWithHandlers = scope.Resolve<ISomeClass>();
}
}
}
}
Notice that I am registering a dedicated handler to ISomeClass interface, as well as a generic one for any type of event emitter. My expectation is that SomeClass constructor will be injected with 2 handlers- the generic and the dedicated one.
Unfortunately, that's not the case. What am I doing wrong here?
Thanks.
Upvotes: 1
Views: 640
Reputation: 139758
When you register an interface with As
Autofac does not automatically registers its base interfaces.
So you need to manually tell to Autofac that your DedicatedEventHandler
is also an IEventHandler
with:
builder.RegisterType<DedicatedEventHandler>()
.As<IEventHandler<ISomeClass>>()
.As<IEventHandler>();
If you want to register a type with all its interfaces you can use the AsImplementedInterfaces
method.
So the equivalent of the above registration is the following:
builder.RegisterType<DedicatedEventHandler>()
.AsImplementedInterfaces();
Upvotes: 3