2009-08-18 57 views

回答

24

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

21

这不一定如此。只要你的静态记录公开了一种方法:在类似的ASP运行它(比如之前的类

  • 注入你想注入,或
  • 注射的DI容器在适当的方法调用.net global.asax Application_Start方法),那么你应该没问题。

下面是一个例子。看看下面的类DI:

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

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

下面是我们的静态类,它需要一个记录:

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


    } 

现在,在全球启动了您的应用程序(在这种情况下,我的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"); 

     } 

而且急!你现在已经开始在你的静态类中使用DI了。

希望能帮助别人。我正在重新开发一个使用很多静态类的应用程序,我们现在已经成功地使用了它。

+5

在我看来更像是依赖解析比依赖注入。静态类现在已经了解了依赖框架。但要避免它,并不难。 (在application_start中解析并使用已解析的依赖项进行初始化,而不是在初始化时提供解析器。) – 2014-09-02 15:52:39

+0

问题是关于将静态类注入静态类。这涉及如何将非静态实例注入静态类。 这看起来像是对以前的回答中的以下陈述的回应:“同样很难将任何东西注入静态类” – 2015-05-11 15:25:17

+0

对于像记录器这样简单的事情,这看起来过于复杂。 – rolls 2017-04-30 03:34:29

0

我不确定记录器是如何工作的,但通常您可以使用RequestService来获取您的实例。例如在抽象类中:

this.HttpContext.RequestServices.GetService(typeof(YOUR_SERVICE)); 

对于控制器,您可以访问HttpContext。

第二种方式是在启动,在那里你可以做到这一点使用它,例如:

serviceCollection.AddScoped(typeof(ICmsDataContext), typeof(TDbContext)); 

其中serviceCollection是IServiceCollection在DOTNET核心。

希望它有帮助。

1

这是一个非常简单的方法来“注入”静态记录器的功能。

public static class Logger 
{ 
    private static Action<string, Exception> _logError; 
    public static bool Initialised; 

    public static void InitLogger(Action<string, Exception, bool> logError) 
    { 
     if(logError == null) return; 
     _logError = logError 
     Initialised = true; 
    } 

    public static void LogError(string msg, Exception e = null) 
    { 
     if (_logError != null) 
     { 
      try 
      { 
       _logError.Invoke(msg, e); 
      } 
      catch (Exception){} 
     } 
     else 
     { 
      Debug.WriteLine($"LogError() Msg: {msg} Exception: {e}"); 
     } 
    } 
} 

public class MainViewModel 
{ 
    public MainViewModel() 
    { 
     //Inject the logger so we can call it globally from anywhere in the project 
     Logger.InitLogger(LogError); 
    } 
    public void LogError(string msg, Exception e = null) 
    { 
     //Implementation of logger 
    } 
}