Question

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.

Was it helpful?

Solution

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();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top