欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 名人名企 > 基于AOP+Log4Net+AutoFac日志框架

基于AOP+Log4Net+AutoFac日志框架

2025/5/11 8:13:58 来源:https://blog.csdn.net/ly1h1/article/details/147170487  浏览:    关键词:基于AOP+Log4Net+AutoFac日志框架

1.项目概述

这是一个基于 C# 的 WPF 项目 WpfApp12log4net,它综合运用了依赖注入、日志记录和接口实现等多种技术,同时使用了 AutofacCastle.Core 和 log4net 等第三方库。

2.配置log4net 

 新建一个Log4Net.config,配置需要记录的日志信息,主要该文件在编译后要生成到debug或者release文件夹下。

配置文件如下:

<?xml version="1.0" encoding="utf-8"?><log4net><!--错误日志类--><logger name="logerror"><!--日志类的名字--><level value="ALL" /><!--定义记录的日志级别--><appender-ref ref="ErrorAppender" /><!--记录到哪个介质中去--></logger><!--信息日志类--><logger name="loginfo"><level value="ALL" /><appender-ref ref="InfoAppender" /></logger><!--MES日志类--><logger name="Mesinfo"><level value="ALL" /><appender-ref ref="MesAppender" /></logger><!--错误日志附加介质--><appender name="ErrorAppender" type="log4net.Appender.RollingFileAppender"><!-- name属性指定其名称,type则是log4net.Appender命名空间的一个类的名称,意思是,指定使用哪种介质--><param name="File" value="Log\\LogError2\\" /><!--日志输出到exe程序这个相对目录下--><param name="AppendToFile" value="true" /><!--输出的日志不会覆盖以前的信息--><param name="MaxSizeRollBackups" value="100" /><!--备份文件的个数--><param name="MaxFileSize" value="1024" /><!--当个日志文件的最大大小--><param name="StaticLogFileName" value="false" /><!--是否使用静态文件名--><param name="DatePattern" value="yyyyMMdd&quot;.txt&quot;" /><!--日志文件名--><param name="RollingStyle" value="Date" /><!--文件创建的方式,这里是以Date方式创建--><!--错误日志布局--><layout type="log4net.Layout.PatternLayout"><param name="ConversionPattern" value="%n异常时间:%d [%t]  %n异常级别:%-5p  %n异 常 类:%c [%x]  %n%m  %n "  /></layout></appender><!--信息日志附加介质--><appender name="InfoAppender" type="log4net.Appender.RollingFileAppender"><param name="File" value="Log\\LogInfo\\"/><param name="AppendToFile" value="true"/><param name="MaxFileSize" value="10240"/><param name="MaxSizeRollBackups" value="100" /><param name="StaticLogFileName" value="false" />  <param name="DatePattern" value="yyyyMMdd&quot;.txt&quot;" /><param name="RollingStyle" value="Date" /><!--信息日志布局--><layout type="log4net.Layout.PatternLayout"><param name="ConversionPattern" value="[时间] %d [%t] [信息] %m%n"  /></layout></appender><!--信息日志附加介质--><appender name="MesAppender" type="log4net.Appender.RollingFileAppender"><param name="File" value="Log\\MesInfo\\"/><param name="AppendToFile" value="true"/><param name="MaxFileSize" value="10240"/><param name="MaxSizeRollBackups" value="100" /><param name="StaticLogFileName" value="false" /><param name="DatePattern" value="yyyyMMdd&quot;.txt&quot;" /><param name="RollingStyle" value="Date" /><!--信息日志布局--><layout type="log4net.Layout.PatternLayout"><param name="ConversionPattern" value="[时间] %d [%t] [信息] %m%n"  /></layout></appender></log4net>

3.加载配置文件

要在代码启动的时候加载,以下是涉及到其他配置,所以是动态路径的案例。

  string configFilePath = "Log4Net.config";var fileInfo = new FileInfo(configFilePath);if (!fileInfo.Exists){throw new FileNotFoundException($"配置文件 {configFilePath} 不存在!");}XmlConfigurator.Configure(fileInfo);string path = @"C:\\Log4NetTestFile\\";string[] fileName = { "InfoAppender", "ErrorAppender", "MesAppender" };ILoggerRepository repository = LogManager.GetRepository(Assembly.GetEntryAssembly());for (int i = 0; i < fileName.Length; i++){log4net.Appender.RollingFileAppender appender = repository.GetAppenders().OfType<log4net.Appender.RollingFileAppender>().FirstOrDefault(a => a.Name == fileName[i]);if (appender != null){appender.File = path + fileName[i] + "\\";appender.ActivateOptions();}}

4.搭建日志方法类LogHelp

日志存储的方法写在里面。

using log4net;
using log4net.Config;
using System;
using System.IO;namespace WpfApp12log4net
{public class LogHelp{private  readonly ILog log_info = LogManager.GetLogger("loginfo");private  readonly ILog log_error = LogManager.GetLogger("logerror");private  readonly ILog mes_info = LogManager.GetLogger("Mesinfo");public  void Info(string info){if (log_info.IsInfoEnabled){log_info.Info(info);}}public  void mesinfo(string info){if (mes_info.IsInfoEnabled){mes_info.Info(info);}}public  void Error(string error, Exception ex){if (log_error.IsErrorEnabled){log_error.Error(error, ex);}}public  void Error(string error){if (log_error.IsErrorEnabled){log_error.Error(error);}}}
}

4.拦截器搭建LoggingInterceptor

using Castle.DynamicProxy;
using log4net;
using System;
using System.Reflection;namespace WpfApp12log4net
{public class LoggingInterceptor : IInterceptor{private readonly LogHelp logHelp;public LoggingInterceptor(LogHelp logHelp){this.logHelp = logHelp;}public void Intercept(IInvocation invocation){try{logHelp.Info($"开始执行方法: {invocation.Method.Name}");logHelp.Info($"参数: {string.Join(", ", invocation.Arguments)}");// 执行方法并获取返回值invocation.Proceed();object result = invocation.ReturnValue;// 记录返回值(如果方法不是 void)sif (invocation.Method.ReturnType != typeof(void)){logHelp.Info($"方法 {invocation.Method.Name} 返回值: {result ?? "null"}");}logHelp.Info($"方法 {invocation.Method.Name} 执行完毕");}catch (Exception ex){// 记录完整的异常信息(包括堆栈跟踪)logHelp.Error($"方法 {invocation.Method.Name} 执行出错: {ex.ToString()}", ex);throw; // 重新抛出异常,确保调用方能够捕获}}}
}

5.创建服务类

    using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace WpfApp12log4net{public class Service : IService{public string methodservice11(string ttt){try{string[] str = null;if (str[1] == "1"){// 此部分代码会触发异常}else{// 此部分代码会触发异常}}catch (Exception ex){//LogHelp.Error(ex.Message);//LogHelp.Error("异常", ex);}return "这是参数返回........的内容";}public string methodservice12(string ttt){try{//string[] str = null;//if (str[1] == "1")//{//    // 此部分代码会触发异常//}//else//{//    // 此部分代码会触发异常//}}catch (Exception ex){//LogHelp.Error(ex.Message);//LogHelp.Error("异常", ex);}return "这是参数返回........的内容";}}}using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace WpfApp12log4net
{public class Service2 : IService2{public string methodservice21(string ttt){try{string[] str = null;if (str[1] == "1"){// 此部分代码会触发异常}else{// 此部分代码会触发异常}}catch (Exception ex){//LogHelp.Error(ex.Message);//LogHelp.Error("异常", ex);}return "这是参数返回........的内容";}}
}

6.创建服务接口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace WpfApp12log4net
{public interface IService{string methodservice11(string ttt);string methodservice12(string ttt);}
}using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace WpfApp12log4net
{public interface IService2{string methodservice21(string ttt);}
}

7.依赖注入

          var builder = new ContainerBuilder();var proxyGenerator = new ProxyGenerator();// 先注册 LogHelpbuilder.RegisterType<LogHelp>().AsSelf();// 注册 LoggingInterceptorbuilder.RegisterType<LoggingInterceptor>().AsSelf();// 注册 IService 接口及其实现类 Servicebuilder.Register(c =>{var service = new Service();var interceptor = c.Resolve<LoggingInterceptor>();return proxyGenerator.CreateInterfaceProxyWithTarget(typeof(IService), service, interceptor) as IService;}).As<IService>();// 注册 IService2 接口及其实现类 Service2builder.Register(c =>{var service = new Service2();var interceptor = c.Resolve<LoggingInterceptor>();return proxyGenerator.CreateInterfaceProxyWithTarget(typeof(IService2), service, interceptor) as IService2;}).As<IService2>();// 注册 MainWindowbuilder.RegisterType<MainWindow>().AsSelf();Container = builder.Build();

8.总结

1. 依赖注入(Dependency Injection,DI)

使用 Autofac 库实现依赖注入。通过 ContainerBuilder 构建容器,注册接口及其实现类(如 IService 与 ServiceIService2 与 Service2 )以及窗口类(MainWindow )等,在程序运行时由容器负责创建对象并注入依赖关系,降低组件间耦合度。

2. 动态代理(Dynamic Proxy)

借助 Castle.DynamicProxy 库实现动态代理。定义了 LoggingInterceptor 类实现 IInterceptor 接口,在方法执行前后进行日志记录等操作。在注册服务时,利用 ProxyGenerator 创建代理对象,将拦截器应用到目标服务(ServiceService2 )上,实现对服务方法调用的拦截和增强 。

3. 日志记录

运用 log4net 日志框架进行日志记录。通过配置文件(log4net.config )设置不同类型日志(错误日志、信息日志、MES 日志 )的记录方式,包括日志级别、日志存储路径、文件滚动策略、日志格式等。在代码中通过 LogHelp 类封装的方法,在不同业务场景(方法执行、异常处理等 )下记录日志。

4. WPF(Windows Presentation Foundation)

这是一个 WPF 项目,使用 WPF 技术构建桌面应用程序界面。定义了 MainWindow 类继承自 Window,实现窗口相关功能,如按钮点击事件处理等,利用 WPF 的特性来呈现用户界面和交互逻辑。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词