1

Reposting here... hopefully the better place to seek opinions on the matter. :)

Writing my own log4net wrapper class using C#. I want to create a lib such that I can reference it from any project/assembly in a given solution with a minimum of effort. ie: include the reference, maybe throw in a using statement and then make calls like MyLogger.Debug(blahblah); with perhaps a property (MyLogger) being set from a "main" method somewhere.

From reading the docs, I'm not sure if I should be writing my own or using LogImpl? The latter seems to include all of what I'd want to put in my own wrapper, so, why reinvent the wheel? But, there is also a note in the help that says thast an instance member of type logimpl is not thread safe whereas a static member is...

OTOH, if I make my own, I'd be looking at a singleton class I can create once and use throughout my solution (by passing the singleton ref to objects which require it) but I gotta rewrite all those Debug, Error, etc sections.

So... not sure what approach to take. What would you folks suggest as a beginning?

2

Generally singletons are considered bad:

...if you still feel the need to use Singleton objects, consider using the Factory Method pattern instead. It gives you all of the flexibility of the Singleton, with nowhere near as many problems.

...and you're supposed to inject the logger implementation into any class that uses it (or inject a logger factory if you only want the logger object to exist for as long as your class is using it), so:

interface IMyLogger
{
    void Log(string whatever);
}

class MyClass
{
    private readonly IMyLogger logger;

    public(IMyLogger logger)
    {
        if(logger == null) throw new ArgumentNullException("logger");
        this.logger = logger;
    }

    void someOtherMethod()
    {
        this.logger.Log("Something");
    }
}

This allows you to inject various different logger implementations. If you decide to go the shortcut route and use a Singleton, and then use the built-in one from log4net then you're pretty much coupling every class that uses it directly to your implementation, which is generally a bad idea.

  • 1
    ILogger is a log4net interface, so I presume you meant to name it something else (otherwise, you're tying log4net directly into any class that implements logging, rather than a singleton, which could have the underlying implementation changed at any point. Why do you say singletons are bad, anyway (I've not yet heard that...)? Back to the example... what do you mean by "you're supposed to inject the logger implementation into any class that uses it"? Why an interface vs a singleton class? Looks like we're a few pages apart... LOL – Jon Mar 31 '14 at 19:22
  • 1
    @Jon - sorry, I fixed it by changing ILogger to IMyLogger. I did intent it to be my own iplementation. As for why singletons are bad, that has been covered before. You might also consider that within the context of your program when it's executing, there is only one instance of IMyLogger, so it's kind of a singleton, but you still have flexibility. Also see Dependency Injection. – Scott Whitlock Mar 31 '14 at 19:28
  • 1
    @Jon What he means to say is that you should pass the logger to the constructor of the objects that need it. Forcing the object to know how to get a logger adds unnecessary coupling. – Doval Mar 31 '14 at 19:31
  • 1
    I don't agree with you Scott, injecting a logger creates a footprint of at least one dependency to the logger on every class that logs. Logging is just an infrastructure related item. The abstraction on a logging does not make sense in that case, just make a wrapper around logging and use your logger of choice as internal member. When having your logger wrapper you create a many to one dependency to the log wrapper so you can easly exchange the logger internally and you don't pollute your classes where you log... – Patrick Peters Mar 31 '16 at 9:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.