My solutions has several projects which includes several libraries and one project for UI. Currently it is a windows forms application and I use log4net for logging. This UI project has only reference to log4net and this project maintains the configuration files. But I would like to log from my libraries as well.
Usual method for doing this is to wrap the logging calls behind an interface. Create a common project something called utilities and add this interface to this project. Now this project can be used in all the projects and can use this interface for logging.
I am thinking about an alternative design which involves passing delegates and reducing coupling and avoiding unnecessary interfaces.
Consider following class is one from my library.
public sealed class Foo
{
Action<string> log;
Action<string, Exception> logException;
public Foo(Action<string> log, Action<string,Exception> logException)
{
this.log = log;
this.logException = logException;
}
public void Work()
{
WL("Starting work");
WL("Completed step1");
.........
}
void WL(string message)
{
if(log != null) log(message);
}
void WL(string message, Exception exception)
{
if(logException != null) logException(message, exception);
}
}
Now from the calling code, I can easily pass the logging method. Something like
Foo foo = new Foo(message => Console.WriteLine(message),
(message, exception) => Console.WriteLine("{0},{1}", message, exception));
foo.Work();
Used a console for explaining, in reality I will use the logging code here.
1 - Do you think this as a better solution? I think this is better as this is more loosely coupled.
2 - Is there any other better solutions available?
This is the only related question I have found here
Any thoughts...?
Don't use delegates if there are multiple signatures flying in close formation. All you're doing is avoiding defining classes and interfaces that would be meaningful. log4net provides an ILog
interface which is an excellent example of a simple wrapper interface you can pass in.
If you're going to use a logging framework, especially log4net, don't wrap it and don't create a single global (static OR singleton) entry point. I've written about this before, and you may be interested in the question about best practices as well.
I have a thin layer that exposes a logging API very similar to Log4Net, that uses a provider-model design pattern to allow you to plug in any suitable logging framework. I've implemented providers for:
System.Diagnostics.Trace
log4net
EntLib
This means I can use logging throughout all my apps without any direct dependency on a specific logging framework, and users of my components can plug in their own favorite logging framework.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With