首页 > 解决方案 > 静态类的 DI

问题描述

我想在我的网站上记录错误。日志类需要 IHostingEnvironment 来获取日志文件路径。DI 仅适用于构造函数,但静态类没有构造函数。

我删除了静态并添加构造函数,但现在当我启动 Log 类时,构造函数正在询问 IHostingEnvironment 参数。最后我需要使用 IHostingEnvironment 我所有的控制器来使用日志类吗?

.net Core 从浏览器调用不带参数的控制器类。请问我怎样才能对我的日志类做同样的事情?

这就是目前的情况。

public class LogServices
{
    public static void Log(string logMessage, IHostingEnvironment env)
    {
        string logName = env.WebRootPath + "\\Log\\Log_" + DateTime.Now.ToString("dd_MM_yyyy") + ".txt";
        using (StreamWriter w = File.AppendText(logName))
        {
            w.Write("\r ");
            w.WriteLine($"  :{logMessage}");
        }
    }
 }

但我想要这样的东西:

public class LogServices
{
    public static void Log(string logMessage,[FromServices] IHostingEnvironment env)
    {
        string logName = env.WebRootPath + "\\Log\\Log_" + DateTime.Now.ToString("dd_MM_yyyy") + ".txt";
        using (StreamWriter w = File.AppendText(logName))
        {
            w.Write("\r ");
            w.WriteLine($"  :{logMessage}");
        }
    }
 }

如果这可行,我可以像这样调用日志文件

  LogServices.Log("Error bal balblaa");

但显然它不起作用,因为 LogServices.Log 再次询问 IHostingEnvironment 参数。和第一个类似。

标签: c#asp.net-coredependency-injection

解决方案


不要使用静态类。将您的注入类注册为单例,并IHostingEnvironment在构造函数中请求。

public class LogServices
{
    private readonly IHostingEnvironment _env;

    public LogServices(IHostingEnvironment env)
    {
        _env = env;
    }

    public void Log(string logMessage)
    {
        string logName = _env.WebRootPath + "\\Log\\Log_" + DateTime.Now.ToString("dd_MM_yyyy") + ".txt";
        using (StreamWriter w = File.AppendText(logName))
        {
            w.Write("\r ");
            w.WriteLine($"  :{logMessage}");
        }
    }
}

然后在你的ConfigureServices方法中Startup.cs

services.AddSingleton<LogServices>();

然后在任何你需要它的地方,你可以在构造函数中请求它,LogServices它会被注入。

但是你也可以考虑让它继承ILogger并使用内置的日志框架。你可以在这里阅读。最大的好处是,每当您记录某些内容时,它都会写入每个已注册的记录器,而不仅仅是一个。所以它仍然可以写入调试窗口以及您的自定义记录器,而无需任何额外代码。

虽然它涉及更多。这里有一个创建您自己的日志记录提供程序以写入文件的完整示例


推荐阅读