Search code examples
c#autofacnlogmasstransit

NLog with Autofac in MassTransit 6.0?


My Consumers fail to instantiate from Autofac due to the following:

Cannot resolve parameter 'Microsoft.Extensions.Logging.Logger1[MyConsumer] logger' of constructor 'Void .ctor(MyService, Microsoft.Extensions.Logging.Logger1[MyConsumer])'.

The ILoggers resolve fine in every other class except the MassTransit Consumers; I believe it's an issue with LogContext.ConfigureCurrentLogContext(); and order of operations. Below is the code, edited for brevity:

ContainerBuilder builder = new ContainerBuilder(); // Autofac

builder.RegisterType<LoggerFactory>()
                         .As<ILoggerFactory>()
                         .SingleInstance();

builder.RegisterGeneric(typeof(Logger<>))
                         .As(typeof(ILogger<>))
                         .SingleInstance();

builder.RegisterAssemblyTypes() // load up all services, yada yada

// what to pass here? I'm inside an unbuilt Autofac Container at this point. There is no ILoggerFactory until the Container is built!
LogContext.ConfigureCurrentLogContext(); // configure MassTransit logging

builder.AddMassTransit(x => 
            {
                x.AddConsumers(Assembly.GetEntryAssembly());

                x.AddBus(bus => MassTransit.Bus.Factory.CreateUsingRabbitMq(config =>
                {
                    config.ConfigureEndpoints(bus); // wire-up consumers discovered by the AddConsumers() call above
                }));
            });

Container = builder.Build(); // now build the container

// add NLog
IServiceProvider serviceProvider = new AutofacServiceProvider(Container); // this requires a built Container!
ILoggerFactory loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
loggerFactory.AddNLog();

I should note that logging within MassTransit is actually working; I see all kind of debug output regarding the queues and messages. But the Consumer will not instantiate for whatever reason. If I try to manually Resolve<ILogger<MyConsumer>>() I'll get an ILogger but MassTransit seems to have trouble with it.

Edit: full error message via VS Output:

None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'MyConsumer' can be invoked with the available services and parameters:
Cannot resolve parameter 'Microsoft.Extensions.Logging.Logger 1[MyConsumer] logger' of constructor 'Void .ctor(MyService, Microsoft.Extensions.Logging.Logger`1[MyConsumer])'.*

Package versions:

  • Autofac.Extensions.DependencyInjection 5.0.1
  • MassTransit 6.0
  • MassTransit.Autofac 6.0
  • NLog.Extensions.Logging 1.6.1

Solution

  • Cannot resolve parameter Microsoft.Extensions.Logging.Logger 1[MyConsumer] logger

    This error message means that Autofac can't find a registered Logger<MyConsumer>. If you look at your registration you register ILogger<> and not Logger<>. You should change the dependency to the interface version in MyConsumer and autofac will find it.