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.

有帮助吗?

解决方案

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();
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top