3

I am using Autofac as DI tool in my project and NLog for the logging.

I am facing a problem to specify the logger name while using NLog with Autofac.

Here is the link to my code.

As you can see, In LoggerService.cs, line: 11

I am creating the instance of logger in constructor. How can I inject the logger object there and also get the logger name as the class name?

Any help will be appreciated.

Update: I have seen the question before. That was about wrong callsite info in logged message. I want to know how to inject logger in class with proper logger name.

Update: Adding relevant code in the question itself.

Global.asax.cs

using Autofac;
using Autofac.Integration.Mvc;
using System.Web.Mvc;
using System.Web.Routing;
using WebApplication2.Utils;

namespace WebApplication2
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            ConfigureAutofac();

            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);
        }

        private void ConfigureAutofac()
        {
            var builder = new ContainerBuilder();

            builder.RegisterControllers(typeof(MvcApplication).Assembly);
            builder.RegisterType<MailService>().As<IMailService>();

            //builder.RegisterModule<NLogModule>();

            builder.RegisterGeneric(typeof(LoggerService<>)).As(typeof(ILoggerService<>)).InstancePerDependency();

            var container = builder.Build();

            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
        }
    }
}

HomeController.cs

using System.Web.Mvc;
using WebApplication2.Utils;

namespace WebApplication2.Controllers
{
    public class HomeController : Controller
    {
        public IMailService mailService { get; set; }
        public ILoggerService<HomeController> loggingService;

        public HomeController(IMailService mailService, ILoggerService<HomeController> loggingService)
        {
            this.mailService = mailService;
            this.loggingService = loggingService;
        }

        // GET: Home
        public ActionResult Index()
        {
            loggingService.Debug("Log message from index method");
            loggingService.Info("Some info log");

            mailService.Send();

            return View();
        }
    }
}

ILoggerService.cs

namespace WebApplication2.Utils
{
    public interface ILoggerService<T>
    {
        void Info(string message);

        void Debug(string message);
    }
}

LoggerService.cs

using NLog;

namespace WebApplication2.Utils
{
    public class LoggerService<T> : ILoggerService<T>
    {
        public ILogger logger { get; set; }

        public LoggerService()
        {
            logger = LogManager.GetLogger(typeof(T).FullName);
        }

        public void Debug(string message)
        {
            logger.Debug(message);
        }

        public void Info(string message)
        {
            logger.Info(message);
        }
    }
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Amitava Karan
  • 637
  • 1
  • 5
  • 20
  • 1
    Please don't link to externally hosted code. Instead, please include the relevant parts of the code into the question. – Steven Apr 17 '17 at 16:41
  • 1
    Possible duplicate of [Injecting NLog with Autofac's RegisterGeneric](http://stackoverflow.com/questions/21919483/injecting-nlog-with-autofacs-registergeneric) – Julian Apr 17 '17 at 22:02
  • @Stevan Sorry for that. I was facing difficulties to format the code here. – Amitava Karan Apr 18 '17 at 05:59
  • I'm not sure what the issue is: logger = LogManager.GetLogger(typeof(T).FullName) is already resolving a logger for a type, using the FullName of the type as a name. – Alberto Chiesa Apr 19 '17 at 09:22
  • Personally, even if I'm a big fan of Autofac, I always register the logger for each class as a static readonly property: `private static readonly Log = LogManager.GetLogger(typeof(CurrentType));`. What value do you think a wrapper around a logger can give you? If you're going to swap NLog for Log4Net, it's just a simple find and replace. YAGNI, in my opinion. – Alberto Chiesa Apr 19 '17 at 09:23
  • Yes, I am getting the correct logger name. Currently I am initiating the logger instance inside the wrapper's constructor. But I like to inject it in the constructor using `autofac` – Amitava Karan Apr 19 '17 at 09:43
  • I understood your point on the wrapper class. IMO, having a wrapper class can minimize the code changes if we switch the logging framework. It may help us write unite testing better. – Amitava Karan Apr 19 '17 at 09:48

2 Answers2

0

Use RegisterGeneric while registering your services, Like below.

builder.RegisterGeneric(typeof(LoggerService<>)).As(typeof(ILoggerService<>)).InstancePerRequest();

mw509
  • 1,957
  • 1
  • 19
  • 25
-1

you can always use LogManager to acquire a logger. looks like this

    private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

Alan_Jin
  • 19
  • 5