Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Friday, July 17, 2015 1:30 PM
I have an uncompleted static class for logging messages.
public static class OutputUtils
{
ILogger logger;
public static void LogTrace(string logMessage, IDictionary<string, string> dict = null)
{
logger.LogTrace(logMessage,dict);
}
public static void LogDebug(string logMessage, IDictionary<string, string> dict=null)
{
logger.LogDebug(logMessage,dict);
}
public static void LogInfo(string logMessage, IDictionary<string, string> dict=null)
{
logger.LogInfo(logMessage,dict);
}
public static void LogWarn(string logMessage, IDictionary<string, string> dict)
{
logger.LogWarn(logMessage,dict);
}
public static void LogError(string logMessage, Exception exception, IDictionary<string, string> dict)
{
logger.LogError(logMessage,exception,dict);
}
public static void LogFatal(string logMessage, Exception exception, IDictionary<string, string> dict)
{
logger.LogFatal(logMessage,exception,dict);
}
Now I have another class to call this static class,
internal sealed class SharedState
{
internal static void WriteLogInfo(string s)
{
OutputUtils.LogInfo(s);
}
}
However I want to generate a new up ILogger in the SharedState class or another class to call SharedState, then we pass the real logger to OutputUtils.cs. I don't want to instantiate the logger in OutputUtils.cs. How?
All replies (5)
Friday, July 17, 2015 8:43 PM âś…Answered
Have you access to the entire source?
Then you may consider changing your static class to a singelton. This would only be a minor change for the production code. But it gives you an instance to work with.
Friday, July 17, 2015 1:49 PM
I would recommend against your static logger approach. This makes it harder to work with. Most likely you only made it static to simplify calls to it but there is a better approach. It appears that you already have an interface representing a logger and your static class is simply a convenience wrapper. Therefore you don't really need it. Have your SharedState class accepts an ILogger instance as a parameter. Inside the class use that instead of your OutputUtils class. This also makes it easier to unit test. If you're using an IoC then the logger is provided by the container otherwise you can use poor man's injection and accomplish the same thing.
internal class SharedState
{
public SharedState ( ) : this(new MyLogger())
{ }
public SharedState ( ILogger logger )
{
_logger = logger;
}
//Public members of an internal class are still internal
public static void WriteLogInfo ( string s )
{
_logger.LogInfo(s);
}
private readonly ILogger _logger;
}
If you do this throughout your code you'll probably come to the realization that you don't really need the static class at all so it basically goes away. The only benefit a static class might provide is giving you access to a shared logger but you don't need static methods for that. Instead you can use something like a singleton.
public class Logger : ILogger
{
//Implement interface here
//Provide a singleton as a default when the logger instance doesn't matter to calling code
public static ILogger Default = new MyLogger();
}
Now you're default constructor of SharedState could use Logger.Default if it wanted to use the default logger or it could be given a new logger depending upon who is using it.
Michael Taylor
http://blogs.msmvps.com/p3net
Friday, July 17, 2015 1:52 PM
However I want to generate a new up ILogger in the SharedState class or another class to call SharedState, then we pass the real logger to OutputUtils.cs. I don't want to instantiate the logger in OutputUtils.cs. How?
Well, you would use an IoC and dependency injection on ILogger, like using Unity, Castel Windsor or other IoC(s). And you would pass in ILogger, which was instantiated by the IoC, into the depended class, class that is using the Logger object, via class constructor injection or dependency property injection into the class that's going to use the Logger object.
Friday, July 17, 2015 2:01 PM
The thing is I am using my new logger to replace the old one. The static class is in the production. I can't change it. The code is pretty old and didn't consider best practices. I only refactor the partial code for the logging messages.
Friday, July 17, 2015 8:35 PM
The thing is I am using my new logger to replace the old one. The static class is in the production. I can't change it. The code is pretty old and didn't consider best practices. I only refactor the partial code for the logging messages.
Since the class is stactic you can not repalce it easily.
If it would be handed in as an instance, extracting an interface and make a different class from that would be simple. The refractor actually has a function for that (extract interface).
You are already working on a partial file, so just make a new code file. Keep the original logger around and develop your own version of the logger class with the same name in the 2nd file. Switching out wich file is to be compiled with the main code (and thus wich of the two identicaly named classes are to be used) should easily doable.