Search code examples
c#design-patternsloggingstaticfactory-pattern

Static factories - good practice?


I've got a static log manager class that should return instances of a desired logger based on a parameter.

public static class LogManager {

    private static ILoggerFactory Factory { ... }

    public static ILogger GetLogger(string name) {
        return Factory.Create(name);
    }

}

Since the concrete implementation of ILoggerFactory must be set (initialization), I'm wondering if I should only keep a reference on the type of the implementation and return a new instance everytime the factory is requested - or if it's okay to keep a static reference of an instance of the implementation.

Version 1

private static Type _factoryType;

public static void SetFactory<TFactory>()
    where TFactory : ILoggerFactory, new()
{
    _factoryType = typeof(TFactory);
}

private static Factory {
    get { return (ILoggerFactory)Activator.CreateInstance(_factoryType);
}

public static ILogger GetLogger(string name) {
    return Factory.Create(name);
}

Version 2

private static ILoggerFactory _loggerFactory;

public static void SetFactory<TFactory>()
    where TFactory : ILoggerFactory, new()
{
    _loggerFactory = (ILoggerFactory)Activator.CreateInstance<TFactory();
}

public static ILogger GetLogger(string name) {
    return _loggerFactory.Create(name);
}

Solution

  • Arguably, main difference appear to be in the lazy loading: v1 will create logger type when GetLogger is called, whereas v2 will create logger during SetFactory. There is not much of a difference otherwise. It is OK to keep a reference as a private static field to either the type of a logger or the factory itself.

    However, if this is production code, I'd get rid of this log manager and factories altogether. Instead I'd use logging framework, like nlog or log4net directly. This simplifies code and makes it more maintainable. Building abstraction in this case is over-engineering.