C# – Dependency injection with a static logger, static helper class

cdependency-injectionstaticunit testing

I have a static class which calls a static Logger class,

e.g

static class DoesStuffStatic
{
  public static void DoStuff()
  {
    try
    {
      //something
    }
    catch(Exception e)
    {
      //do stuff; 
      Logger.Log(e);
    }
  }
}

static class Logger
{
  public static void Log(Exception e)
  {
     //do stuff here
  }
}

How do I inject the Logger into my static class?

Note: I've read Dependency Injection in .NET with examples?, but this seems to use an instance logger.

Best Answer

This is not necessarily so. As long as your static logger exposes a method for:

  • Injection of the classes you WANT injected, or
  • Injection of the DI Container in an appropriate method call prior to running it (say in something like the asp.net global.asax Application_Start method), then you should be fine.

Here's an example. Take the following class for DI:

 public class Logger : ILogger
    {
        public void Log(string stringToLog)
        {
           Console.WriteLine(stringToLog);
        }
    }

    public interface ILogger
    {
        void Log(string stringToLog);
    }

And here's our static class which needs a logger:

public static class SomeStaticClass
    {
        private static IKernel _diContainer;
        private static ILogger _logger;

        public static void Init(IKernel dIcontainer)
        {
            _diContainer = dIcontainer;
            _logger = _diContainer.Get<ILogger>();
        }


        public static void Log(string stringToLog)
        {
            _logger.Log(stringToLog);
        }


    }

Now, in a global startup for your app (in this case, in my global.asax.cs), you can instantiate your DI Container, then hand that off to your static class.

public class Global : Ninject.Web.NinjectHttpApplication
    {

        protected override IKernel CreateKernel()
        {
            return Container;
        }


        static IKernel Container
        {
            get
            {
                var standardKernel = new StandardKernel();
                standardKernel.Bind<ILogger>().To<Logger>();
                return standardKernel;
            }

        }

        void Application_Start(object sender, EventArgs e)
        {
            SomeStaticClass.Init(Container);
            SomeStaticClass.Log("Dependency Injection with Statics is totally possible");

        }

And presto! You are now up and running with DI in your static classes.

Hope that helps someone. I am re-working an application which uses a LOT of static classes, and we've been using this successfully for a while now.