实现目标:将log4net的相关操作封装成一个 .Net Standard类库
demo地址:Step 1 建立解决方案和处理项目相关配置
在当前解决方案下新建项目,选择 .Net Standard类库,命名“MyLogManager”
nuget引用log4net,添加log4net.config配置,右键点击log4net.config,选择“属性”,修改log4net.config文件属性
刚添加的log4net.config文件属性可能如下图所示(生成操作为无,不复制到输出目录)需要修改成如下所示(生成操作 无 改为 内容
,复制到输出目录 - 选择 如果较新则复制
)
重新生成解决方案后,在生成目录中就能看到log4net.config文件
Step 2 上代码
思路:两个StartLogger方法,在程序启动时启动该方法,一个方法自己配置处理,一个走默认
代码如下public class MyLogManager { private static ILoggerRepository _loggerRepository; ////// 启动logger /// /// repository名称 /// 配置文件名称 public static void StartLogger(string repository, string fileName) { _loggerRepository = LogManager.CreateRepository(repository); XmlConfigurator.ConfigureAndWatch(_loggerRepository, new FileInfo(fileName)); } ////// 启动logger /// public static void StartLogger() { _loggerRepository = LogManager.CreateRepository(nameof(MyLogManager)); XmlConfigurator.ConfigureAndWatch(_loggerRepository, new FileInfo("log4net.config")); } public static ILog GetMyLog(T t) { return LogManager.GetLogger(_loggerRepository.Name, t.GetType()); } public static ILog GetMyLog(object obj) { return LogManager.GetLogger(_loggerRepository.Name, obj.GetType()); } public static ILog GetMyLog(Type type) { return LogManager.GetLogger(_loggerRepository.Name, type); } }
封装之后,调用代码会比第一版本的稍微精简
static void TestV1() { MyLogManager.MyLogManager.StartLogger("DotNetCoreConsole_V2", "log4net.config"); var log = MyLogManager.MyLogManager.GetMyLog(typeof(Program)); const int numberOfCycles = 20000; var sw = Stopwatch.StartNew(); for (var i = 0; i < numberOfCycles; i++) { log.InfoFormat("testNum: {0} ", i); } sw.Stop(); Console.WriteLine(); Console.WriteLine("Ellapsed: {0}, numPerSec: {1}", sw.ElapsedMilliseconds, numberOfCycles / (sw.ElapsedMilliseconds / (double)1000)); Console.ReadKey(); }
代码重构和优化
思考:可不可以去掉StartLogger这行代码呢?可以。
实现如下public class NullLogManager { private static ILoggerRepository _loggerRepository; private static ILoggerRepository LoggerRepository { get { if (_loggerRepository != null) { return _loggerRepository; } _loggerRepository = LogManager.CreateRepository(nameof(NullLogManager)); XmlConfigurator.ConfigureAndWatch(_loggerRepository, new FileInfo("log4net.config")); return _loggerRepository; } } public static ILog GetMyLog(T t) { return LogManager.GetLogger(LoggerRepository.Name, t.GetType()); } public static ILog GetMyLog(object obj) { return LogManager.GetLogger(LoggerRepository.Name, obj.GetType()); } public static ILog GetMyLog(Type type) { return LogManager.GetLogger(LoggerRepository.Name, type); } public static ILog GetMyLog() { return LogManager.GetLogger(LoggerRepository.Name, nameof(GetMyLog)); } }
调用代码可再次精简
static void TestNullLogManager() { var log = MyLogManager.NullLogManager.GetMyLog(typeof(Program)); const int numberOfCycles = 20000; var sw = Stopwatch.StartNew(); for (var i = 0; i < numberOfCycles; i++) { log.InfoFormat("testNum: {0} ", i); } sw.Stop(); Console.WriteLine(); Console.WriteLine("Ellapsed: {0}, numPerSec: {1}", sw.ElapsedMilliseconds, numberOfCycles / (sw.ElapsedMilliseconds / (double)1000)); Console.ReadKey(); }