creo que lo mejor es que sea sencillo, tal vez algo como esto:
public static class LoggerFactory
{
static readonly Dictionary<Type, Type> loggers = new Dictionary<Type, Type>();
public static void AddLoggerProvider<T, TLogger>() where TLogger : ILogger<T>, new()
{
loggers.Add(typeof(T), typeof(TLogger));
}
public static ILogger<T> CreateLogger<T>()
{
//implement some error checking here
Type tLogger = loggers[typeof(T)];
ILogger<T> logger = (ILogger<T>) Activator.CreateInstance(tLogger);
return logger;
}
}
que acaba de llamar la AddLoggerProvider
para cada tipo que desea apoyar, se puede ampliar en tiempo de ejecución, se garantiza que definitivamente añade una la implementación de la interfaz para la biblioteca y no algún objeto, no es muy rápida debido al Activator
, pero la creación de un registrador probablemente no sea un cuello de botella de todos modos. Espero que se vea bien.
Uso:
// initialize somewhere
LoggerFactory.AddLoggerProvider<String, StringLogger>();
LoggerFactory.AddLoggerProvider<Exception, ExceptionLogger>();
// etc..
ILogger<string> stringLogger = LoggerFactory.CreateLogger<string>();
Nota: cada ILogger<T>
requiere un constructor sin parámetros para la Activator
, pero eso también está garantizado con el new()
limitación genérica en el método add.
En realidad, el uso del Activador es muy lento: http://www.csharp-architect.com/post/2009/06/11/Generic-new-T%28%29- Performance-Issue-and-a-Solution.aspx –
Escribí "no es muy rápido debido al Activador", por lo que no es exclusivo con "es muy lento" :) –