Reputation: 919
I would like to log errors on my website. Log class needs IHostingEnvironment to get the log file path. DI only works constructor but static class doesn't have constructor.
I removed the static and add constructor but now when i initiate the Log class, constructor is asking IHostingEnvironment parameter. At the end i need to use IHostingEnvironment all my controllers to use log class?
.net Core calls Controller class without parameters from browser. How can i do the same with my log class please?
This is how it is at the moment.
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}");
}
}
}
But I want something like this:
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}");
}
}
}
If this works, I can just call log file like this
LogServices.Log("Error bal balblaa");
But obviously it isn't working because LogServices.Log is asking IHostingEnvironment parameter again. Similar to first one.
Upvotes: 0
Views: 528
Reputation: 40858
Don't use a static class. Register your class for injection as a singleton, and ask for IHostingEnvironment
in the constructor.
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}");
}
}
}
Then in your ConfigureServices
method in Startup.cs
:
services.AddSingleton<LogServices>();
Then anywhere you need it, you can ask for LogServices
in the constructor and it will get injected.
But you can also consider making it inherit from ILogger
and using the built-in logging framework. You can read about it here. The greatest benefit is that whenever you log something, it will write to every registered logger, not just one. So it could still write to the debug window, as well as your custom logger, without any extra code.
It is a little more involved though. There is a full example of creating your own logging provider to write to a file here.
Upvotes: 4