使用静态记录器,静态助手类进行依赖注入

gee*_*jay 29 c# static unit-testing dependency-injection

我有一个静态类,它调用静态Logger类,

例如

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
  }
}
Run Code Online (Sandbox Code Playgroud)

如何将Logger注入我的静态类?

注意:我已经通过示例阅读了.NET中的依赖注入?,但这似乎使用实例记录器.

Grz*_*nio 34

您无法注入静态记录器.您必须将其更改为实例记录器(如果可以),或将其包装在实例记录器中(将调用静态).同样很难向静态类注入任何东西(因为你不以任何方式控制静态构造函数) - 这就是为什么我倾向于传递我想要作为参数注入的所有对象.


小智 30

这不一定是这样.只要您的静态记录器公开以下方法:

  • 注入你想注入的课程,或
  • 在运行它之前在适当的方法调用中注入DI容器(比如像asp.net global.asax Application_Start方法),那么你应该没问题.

这是一个例子.参考以下课程:

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

    public interface ILogger
    {
        void Log(string stringToLog);
    }
Run Code Online (Sandbox Code Playgroud)

这是我们需要记录器的静态类:

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);
        }


    }
Run Code Online (Sandbox Code Playgroud)

现在,在您的应用程序的全局启动中(在本例中,在我的global.asax.cs中),您可以实例化您的DI容器,然后将其交给您的静态类.

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");

        }
Run Code Online (Sandbox Code Playgroud)

并且presto!您现在已经在静态类中使用DI运行了.

希望能帮助别人.我正在重新使用一个使用大量静态类的应用程序,我们已经成功使用了一段时间了.

  • 在我看来更像是依赖解析而不是依赖注入.静态类现在具有依赖框架的知识.但要避免这种情况并不难以适应它.(在application_start中解析并使用已解析的依赖项进行初始化,而不是在初始化时提供解析程序.) (10认同)