1
\$\begingroup\$

I have some code to write Error Logs to different places like Console/SignalR Messages/Text File.

The code is as follows:-

public class Logger
    {
    public void WriteToLog(string message, LogType logType)
    {
        switch (logType)
        {
            case LogType.Console:
                Console.WriteLine(message);
                break;

            case LogType.SignalR:
                // Code to send message to SignalR Hub
                break;

            case LogType.File:
                // Code to write in .txt file
                break;
        }
    }
}

Where my LogType is a simple Enum as below:-

public enum LogType
{
    Console,
    SignalR,
    File
}

But, when I think of Open-Close Principle, I am not getting optimal solution for it.

Edit:

I need to refactor my code as per open close principle. I need to optimize it, so that I don't need to Modify WriteToLog method once any LogType gets added.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ What is the question? \$\endgroup\$ Oct 4, 2013 at 11:32
  • \$\begingroup\$ @Jean-FrançoisCôté:- I need to refactor my code as per open close principle. I need to optimize it, so that I don't need to Modify WriteToLog method once any LogType gets added. \$\endgroup\$
    – Dimerize
    Oct 4, 2013 at 11:36
  • \$\begingroup\$ Look at realisation of this principle in Log4Net project. It allow to define appenders in configuration file. \$\endgroup\$
    – Vasiliy
    Oct 4, 2013 at 11:39
  • \$\begingroup\$ I'd say this sounds like a school assignment and you shouldn't shoot yorself in the foot by blindly pasting it here instead of thinking about it yourself and learning something. ;-) \$\endgroup\$
    – EagleBeak
    Oct 4, 2013 at 12:39

2 Answers 2

2
\$\begingroup\$

Create an interface which will implement your logic for Logging:- Say:

public interface ILogger {
        void LogMessage(string message);
    }

Create a new class for all message type in place of Enum, later stages if any new LogType gets added, respective class can be included without changing your existing Logic:

public class SignalRLogger : ILogger
    {
        public void LogMessage(string message)
        {
            throw new NotImplementedException();//your Implementaion here
        }
    }

Now, your implementation would be very similar as below:-

public class Logger
    {
        ILogger _logger;

        public Logger(ILogger messageLogger)
        {
            _logger = messageLogger;
        }

        public void Log(string message)
        {
            _logger.LogMessage(message);
        }
    }
\$\endgroup\$
5
\$\begingroup\$

You should create an interface from which you can make many implementations, e.g. an ILogger interface with Warning, Error methods etc.

Then you would create an implementation per logging type (one for console, one for SignalR etc). You could then inject the ILogger into any type that requires it (or another approach is to use a static field and resolve the logger through a static log manager type).

You might also want to consider a library such as Common.Logging which already provides an interface and several implementations already available, e.g. NLog, log4net etc.

Another consideration is whether you wish to mix business logic and logging code. Other alternatives are an AOP approach (PostSharp is one option) or semantic logging.

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.