使用静态记录器,静态助手类进行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 } } 

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

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

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

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

  • 注入你想要注入的类,或者
  • 在运行它之前在适当的方法调用中注入DI容器(比如像asp.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(); } 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().To(); return standardKernel; } } void Application_Start(object sender, EventArgs e) { SomeStaticClass.Init(Container); SomeStaticClass.Log("Dependency Injection with Statics is totally possible"); } 

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

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

这是“注入”静态记录器function的一种非常简单的方法。

 public static class Logger { private static Action _logError; public static bool Initialised; public static void InitLogger(Action 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 } } 

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

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

控制器是可能的,您可以在其中访问HttpContext。

第二种方法是在Startup中使用它,您可以在其中执行此操作:

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

其中serviceCollection是dotnet Core中的IServiceCollection

希望它有所帮助。