4

I have mostly used Ninject, so I apologize if I mix up terminology.

I created a logger module to handle NLog using the destination class name as the logger name. It is very similar to this: http://docs.autofac.org/en/latest/examples/log4net.html?highlight=log4net

I also have a module created in my service layer that takes care of all of the service level registrations. Looks like this:

public class ServiceModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
       builder.Register(x => new AccountService(x.Resolve<ILogger>()))
            .As<IAccountService>()
            .InstancePerRequest();
    }
}

Here is my autofac registration:

var builder = new ContainerBuilder();

builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterModule(new LoggingModule());
builder.RegisterModule(new ServiceModule());

var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

app.UseAutofacMiddleware(container);
app.UseAutofacMvc();

At runtime, I get an exception saying ILogger has not been registered, am I missing something about how the modules work that is causing ILogger to not be visible in my service module?

Dan Hunex
  • 5,172
  • 2
  • 27
  • 38
Dan
  • 1,101
  • 1
  • 9
  • 30

1 Answers1

2

A module can do many things : it can register new components and/or subscribe to Autofac events.

In this case, the LoggingModule doesn't register ILog. It intercepts the preparation of other components using the Preparing event and add a new Parameter that will create the ILog if needed.

You won't be able to resolve ILog but if your AccountService implementation requires a ILog the following Parameter will be triggered and will provide the ILog implementation.

new ResolvedParameter(
    (p, i) => p.ParameterType == typeof(ILog),
    (p, i) => LogManager.GetLogger(p.Member.DeclaringType)
)

All you have to do is to register your type without trying to explicitly create the instance :

builder.RegisterType<AccountService>()
       .As<IAccountService>()
       .InstancePerRequest();
Cyril Durand
  • 15,834
  • 5
  • 54
  • 62
  • Ok that makes sense since I tried changing my registration to Type registration and it was working. How would I go about getting the module to work with resolve statements, any documentation you can point me too on that subject? – Dan May 09 '16 at 16:12
  • Have a look at `IRegistrationSource` : http://docs.autofac.org/en/latest/advanced/registration-sources.html – Cyril Durand May 09 '16 at 18:49