Trying to use Autofac to inject a log4net class into my controller, but I get the following exception:
None of the constructors found with 'Public binding flags' on type 'MvcApplication6.Controllers.HomeController' can be invoked with the available services and parameters: Cannot resolve parameter 'log4net.ILog logger' of constructor 'Void .ctor(log4net.ILog)'.
I have created a module to inject the Log
class using the correct type:
public class LogInjectionModule : Module
{
protected override void AttachToComponentRegistration(IComponentRegistry registry, IComponentRegistration registration)
{
registration.Preparing += OnComponentPreparing;
}
static void OnComponentPreparing(object sender, PreparingEventArgs e)
{
var t = e.Component.Activator.LimitType;
e.Parameters = e.Parameters.Union(new[]
{
new ResolvedParameter((p, i) => p.ParameterType == typeof(ILog), (p, i) => LogManager.GetLogger(t))
});
}
}
I then register the module within my ASP.NET MVC Application_Start
method:
protected void Application_Start()
{
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterControllers(typeof (MvcApplication).Assembly) ;
var container = builder.Build() ;
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
builder.RegisterModule(new LogInjectionModule());
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
I have added a constuctor to the controller which takes an ILog
as a parameter:
namespace MvcApplication6.Controllers
{
public class HomeController : Controller
{
ILog _log;
public HomeController(ILog logger)
{
_log = logger;
}
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
_log.Info("Log message from Index()");
return View();
}
public ActionResult About()
{
_log.Info("Log message from About()");
return View();
}
}
}
I am sure I have missed a step, so any help would be appreciated.
I'm not sure this is causing your problem but you should try to add the module to the ContainerBuilder before calling builder.Build();
Something like this:
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterControllers(typeof (MvcApplication).Assembly) ;
builder.RegisterModule(new LogInjectionModule());
var container = builder.Build() ;
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
Another suggestion is to not inject the logger. Usually when i design a class, with the constructor dependencies i try to express the logical business dependencies of the component i'm modelling. Logging is mostly an implementation detail that is orthogonal to the application. At least with log4net you can have a static member in any class where you need logging that is created with LogManager.GetLogger(type). To facilitate adding the logger you can use a Visual Studio snippet.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With