1

I am abstracting away NLog. So far, what I have...

public interface IAppLogger
{
    void Info(string message);
    void Warn(string message);
    void Error(string message, Exception error);
    void Fatal(string message);
     ....// other overload
}

And an Implementation of IAppLogger using NLog

public class NLogLogger : IAppLogger
{
    private readonly NLog.Logger _logger;

    public NLogLogger([CallerFilePath] string callerFilePath = "")
    {
       _logger = NLog.LogManager.GetLogger(callerFilePath);
    }

    public void Info(string message)
    {
       _logger.Info(message);
    }

    public void Warn(string message)
    {
       _logger.Warn(message);
    }
    .....// and others
 }

And Console Application that uses this service

public class Program
{
    private static IAppLogger Log { get; set; }

    private static void Main()
    {
        var kernel = new StandardKernel();
        kernel.Load(Assembly.GetExecutingAssembly());
        Log = kernel.Get<IAppLogger>();

        Log.Info("Application Started");
        Log.Warn("Developer: Invalid date format");
        Log.Error("Divid by zero error", new DivideByZeroException());

        Console.WriteLine("\nDone Logging");
        Console.ReadLine();
    }
}

And a dependency Injection using Ninject

public class NinjectConfig : NinjectModule
{
    public override void Load()
    {
        Bind<IAppLogger>().To<NLogLogger>()
         .WithConstructorArgument("callerFilePath", GetParentTypeName);
    }

    private static string GetParentTypeName(IContext context)
    {
        return context.Request.ParentRequest.Service.FullName;
    }
}

so far so good. But When I run the application, Ninject keeps returning NULL for context.Request.ParentRequest. I also tried it with context.Request.Target........ Still it returns NULL for context.Request.Target. What am I doing wrong. Help me out please!!!!

ash
  • 2,902
  • 3
  • 19
  • 34
  • Check this out... http://stackoverflow.com/questions/30457623/how-to-get-implementing-type-during-ninject-dependency-resolve – dbugger May 18 '16 at 15:54
  • @dbugger So what I understand from the link you suggested is that, ParentContext or Target will be null if I accessed Ninject service through IResolutionRoot.Get() like I did on Console application above. GOT IT!!. Thank you very much. – ash May 18 '16 at 16:03
  • But is there a way that a class that get the injection to notify it self to Ninject service using IResolutionRoot so that ParentContext won't be null – ash May 18 '16 at 16:15
  • "I am abstracting away NLog." That's not abstraction away, that's copying the exact API. Consider [this approach](https://stackoverflow.com/questions/5646820/logger-wrapper-best-practice) instead. – Steven May 18 '16 at 18:50
  • @Steven thanks. I like your answer on the link you gave me. – ash May 19 '16 at 07:52
  • you will to adapt the binding if you want the binding to work when the logger is ctor-injected as well as when it is created by `IResolutionRoot.Get()`. One way is two separate bindings with a when condition (which checks whether `IContext.Request.Target`). When null use a ctor-parameter which needs to be supplied by `Get(.. parameter goes here...)`. Parameter could be a `ConstructorArgument` for example. – BatteryBackupUnit May 19 '16 at 21:31
  • @BatteryBackupUnit are you suggesting like kernel.Get( new ConstructorArgument("callerFilePath", param) ); – ash May 20 '16 at 07:58
  • yes. You can put it in a factory so you don't have to do the same thing over and over again. – BatteryBackupUnit May 20 '16 at 13:00

1 Answers1

2

Found an answer here that may work for you, give this a try:

public class NLogLogger : IAppLogger
{
    private readonly NLog.Logger _logger;

    public NLogLogger(Type callerType)
    {
       _logger = NLog.LogManager.GetLogger(callerType.Name,callerType);
    }

    public void Info(string message)
    {
       _logger.Info(message);
    }

    public void Warn(string message)
    {
       _logger.Warn(message);
    }
    .....// and others
 }

public class NinjectConfig : NinjectModule
{
    public override void Load()
    {
        Bind<IAppLogger>().ToMethod(p => new NLogLogger(p.Request.Target.Member.DeclaringType));
    }
}
Community
  • 1
  • 1
P. Roe
  • 2,077
  • 1
  • 16
  • 23
  • 2
    But still p.Request.Target returns NULL. Because I'm asking for the service explicitly through IResolution.Get(), It keeps returning null. – ash May 19 '16 at 07:28