Search code examples
c#dependency-injectionautofac

Can't resolve a registered type in Autofac


I am trying to write integration test for my project (XUnit) that implements dependency injection using Autofac. Specifically I'm trying to test my service layer.

That's why I implemented a "kernel" class that registers all components and has a method that returns component requested in arguments.

public class TestKernel
    {
        private readonly IContainer container;

        public TestKernel()
        {
            var builder = new ContainerBuilder();
            builder.RegisterModule(new ApplicationServicesContainer());
            builder.RegisterModule(new SsspDomainContainer());
            container = builder.Build();
        }

        public T Get<T>() where T : class
        {
            return container.Resolve<T>();
        }
    }

Module that registers services:

 public class ApplicationServicesContainer : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            builder.RegisterType<XService>().As<IXService>();
                                .
                                .
                                .
        }
    }

And then in tests I fetch the service with:

public class XServiceTest : TestKernel
    {
        private readonly XService _service;

        public XServiceTest()
        {
            _service = Get<XService>();
        }

On test execution I get the following error:

Autofac.Core.Registration.ComponentNotRegisteredException : The requested service 'Project.ApplicationServices.Services.XService' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.

Any help is much appreciated


Solution

  • That is because you are requesting a XService, but you registered XService as the IXService interface.

    You have to change it to

        public class XServiceTest : TestKernel
        {
            private readonly IXService _service;
    
            public XServiceTest()
            {
                _service = Get<IXService>();
            }
        }
    

    It is perfectly valid to register a concrete class into the container. For example, you could have done this:

        builder.RegisterType<XService>().As<XService>();
    

    That way, you would have been able to request the XService from the container and it would work as written. This is usually not want you want to do, but can be beneficial in some cases.