C# 使用静态记录器、静态帮助器类进行依赖注入
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1293489/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dependency injection with a static logger, static helper class
提问by geejay
I have a static class which calls a static Logger class,
我有一个静态类,它调用一个静态 Logger 类,
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?
如何将 Logger 注入我的静态类?
Note: I've read Dependency Injection in .NET with examples?, but this seems to use an instance logger.
注意:我已经阅读了 .NET 中的依赖注入和示例?,但这似乎使用了一个实例记录器。
采纳答案by Grzenio
You can't inject a static logger. You have to either change it to an instance logger (if you can), or wrap it in an instance logger (that will call the static). Also it is fairly hard to inject anything to a static class (because you don't control the static constructor in any way) - that's why I tend to pass all the objects I want to inject as parameters.
您不能注入静态记录器。您必须将其更改为实例记录器(如果可以),或者将其包装在实例记录器中(这将调用静态记录器)。此外,向静态类注入任何内容也相当困难(因为您不以任何方式控制静态构造函数)——这就是为什么我倾向于将我想注入的所有对象作为参数传递。
回答by Chris Smith
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.
- 注入您想要注入的类,或
- 在运行之前在适当的方法调用中注入 DI 容器(比如在 asp.net global.asax Application_Start 方法中),那么你应该没问题。
Here's an example. Take the following class for DI:
这是一个例子。参加以下 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.
现在,在您的应用程序的全局启动中(在本例中,在我的 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");
}
And presto! You are now up and running with DI in your static classes.
而且很快!您现在已在静态类中使用 DI 启动并运行。
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.
希望能帮助某人。我正在重新编写一个使用大量静态类的应用程序,我们已经成功使用它一段时间了。
回答by Petr Tomá?ek
I'm not sure how Logger works, but generally you can use RequestServiceto get your instance. For example in abstract class:
我不确定 Logger 是如何工作的,但通常您可以使用RequestService来获取您的实例。例如在抽象类中:
this.HttpContext.RequestServices.GetService(typeof(YOUR_SERVICE));
It is possible for controller, where you can access to HttpContext.
控制器是可能的,您可以在其中访问 HttpContext。
The second way is use it for example in Startup, where you can do this:
第二种方法是在Startup 中使用它,您可以在其中执行以下操作:
serviceCollection.AddScoped(typeof(ICmsDataContext), typeof(TDbContext));
where serviceCollection is IServiceCollectionin dotnet Core.
其中 serviceCollection 是dotnet Core 中的IServiceCollection。
Hope it helped.
希望它有所帮助。
回答by rolls
This is a very simple way to "inject" the functionality of a static logger.
这是“注入”静态记录器功能的一种非常简单的方法。
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
}
}