C# 实现调用函数,打印日志(通过反射代理、非IOC)

news2025/1/10 23:23:27

在这里插入图片描述

🎈个人主页:靓仔很忙i
💻B 站主页:👉B站👈
🎉欢迎 👍点赞✍评论⭐收藏
🤗收录专栏:C#
🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步!


需求:对于不方便debug的程序,查看日志是一个特别好的调试方式,但是在.net framework中,想实现面向切面打印日志特别困难。有人可能会想到使用Castle,使用Castle确实ok。但它需要依赖注入,需要框架去托管所有需要AOP的对象,系统中还有很多静态类,想实现这些都类的日志打印,我还需要去包装类库中的所有的静态类。这显然不现实,本文就是为了解决这个问题而写。

解决方案:为此,笔者写了一个Logger类,提供了CallStatic,CallMethod方式分别去调用方法,调用方法的时候,打印日志。调用思路也很简单,直接调用就行,需要调用的方法,通过参数传递即可。废话不多说,直接上干货。

  • 程序需要三个文件
    在这里插入图片描述
    • Logger:日志类
    • MyService: 测试使用的方法
    • Program: 入口
  • Logger文件
    using System;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Reflection;

    namespace AutoTemplate.log
    {
        public static class Logger
        {
            public static void CallStatic(Expression<Action> expression)
            {
                var methodInfo = (MethodCallExpression)expression.Body;
                var method = GetMethodInfo(methodInfo);
                var parameters = GetParameters(methodInfo);
                PrintStartLog(method, parameters);
                method.Invoke(null, parameters);
                PrintEndLog(method);
            }
            public static T CallStatic<T>(Expression<Func<T>> expression)
            {
                var methodInfo = (MethodCallExpression)expression.Body;
                var method = GetMethodInfo(methodInfo);
                var parameters = GetParameters(methodInfo);

                PrintStartLog(method, parameters);
                var result = (T)method.Invoke(null, parameters);
                PrintEndLog(method);
                return result;
            }

            public static void CallMethod<T>(this T instance, Expression<Action<T>> expression)
            {
                var methodInfo = (MethodCallExpression)expression.Body;
                var method = GetMethodInfo(methodInfo);
                var parameters = GetParameters(methodInfo);

                PrintStartLog(method, parameters);
                method.Invoke(instance, parameters);
                PrintEndLog(method);
            }

            public static TResult CallMethod<T, TResult>(this T instance, Expression<Func<T, TResult>> expression)
            {
                var methodInfo = (MethodCallExpression)expression.Body;
                var method = GetMethodInfo(methodInfo);
                var parameters = GetParameters(methodInfo);

                PrintStartLog(method, parameters);
                var result = (TResult)method.Invoke(instance, parameters);
                PrintEndLog(method);

                return result;
            }

            private static MethodInfo GetMethodInfo(MethodCallExpression methodCall)
            {
                return methodCall.Method;
            }

            private static object[] GetParameters(MethodCallExpression methodCall)
            {
                object[] parameters = methodCall.Arguments.Count > 0
                   ? methodCall.Arguments.Select(arg => Expression.Lambda(arg).Compile().DynamicInvoke()).ToArray()
                   : Array.Empty<object>();
                return parameters;
            }

            private static void PrintStartLog(MethodInfo method, object[] parameters) {
                Console.WriteLine($"==========================================");
                Console.WriteLine($"[Log Start]开始调用方法: {method.Name}({string.Join(", ", parameters)})");
            }

            private static void PrintEndLog(MethodInfo method)
            {
                Console.WriteLine($"[Log End]方法调用成功: {method.Name}");
            }
        }
    }
  • MyService
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AutoTemplate
{
    public class MyService
    {
        public static void NoArgNoResultStaticMethod()
        {
            Console.WriteLine("静态方法:无参无返回值");
        }

        public static void OneArgStaticMethod(string a)
        {
            Console.WriteLine($"静态方法:一个参数无返回值,参数:{a}");
        }

        public static string ResultStaticMethod()
        {
            Console.WriteLine($"静态方法:无参数有返回值,返回值:hello");
            return "这是ResultStaticMethod返回值";
        }

        public void NoArgNoResultMethod()
        {
            Console.WriteLine("方法:无参无返回值");
        }

        public void OneArgMethod(string aaa)
        {
            Console.WriteLine($"方法:一个参数无返回值,参数:{aaa}");
        }

        public int ReturnMethod()
        {
            Console.WriteLine($"方法:无参一个返回值");
            return 0;
        }

        public string OneArgReturnMethod(string e)
        {
            Console.WriteLine($"方法:一个参数一个返回值,参数:{e}");
            return "这是OneArgReturnMethod返回值";
        }

        public string ThreeArgOneResultMethod(string e,float f,int g)
        {
            Console.WriteLine($"方法:三个参数一个返回值,参数:{e},{f},{g}");
            return "这是ThreeArgOneResultMethod返回值";
        }
    }
}

  • Program
using AutoTemplate.log;
using FlaUI.UIA3;
using PATool.Core.Automation;
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;

namespace AutoTemplate
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //静态方法调用
            Logger.CallStatic(() => MyService.NoArgNoResultStaticMethod());
            Logger.CallStatic(() => MyService.OneArgStaticMethod("abc"));
            var staticRes= Logger.CallStatic(() => MyService.ResultStaticMethod());
            var processRes = Logger.CallStatic(() => Process.Start("notepad++"));

            //对象方法调用
            var myService = new MyService();
            myService.CallMethod(s => s.NoArgNoResultMethod());
            myService.CallMethod(s => s.OneArgMethod("hello"));
            var res1=myService.CallMethod(s => s.ReturnMethod());
            var res2=myService.CallMethod(s => s.OneArgReturnMethod("xlwang"));
            var res3 = myService.CallMethod(s => s.ThreeArgOneResultMethod("xlwang",1.2f,5));

        }
    }
}
  • 运行结果
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2202229.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

宝塔面板配置FTP服务结合内网穿透实现其他设备远程连接上传文件

文章目录 前言1. Linux安装Cpolar2. 创建FTP公网地址3. 宝塔FTP服务设置4. FTP服务远程连接小结 5. 固定FTP公网地址6. 固定FTP地址连接 前言 本文主要介绍宝塔FTP文件传输服务如何搭配内网穿透工具&#xff0c;实现随时随地远程连接局域网环境搭建的宝塔FTP文件服务并进行文件…

电商数据淘宝/京东/1688商品SKU数据采集||电商API接口

电商数据采集接口数据分析是一个涉及多个步骤的过程&#xff0c;以下是一个详细的指南&#xff1a; 一、数据采集接口的选择与接入 选择合适的电商数据采集接口&#xff1a; 根据需求选择提供所需数据的电商平台接口。考虑接口的稳定性、数据更新频率及准确性。 接口接入准备&…

《网络数据安全管理条例》正式公布,规范数据处理活动,保障网络数据安全

近日&#xff0c;《网络数据安全管理条例》&#xff08;以下简称《条例》&#xff09;正式公布&#xff0c;自2025年1月1日起施行。 《条例》旨在规范网络数据处理活动&#xff0c;保障网络数据安全&#xff0c;促进网络数据依法合理有效利用&#xff0c;保护个人、组织的合法权…

java时间复杂度与空间复杂度的排序

怎么理解时间复杂度和空间复杂度 时间复杂度和空间复杂度一般是针对算法而言&#xff0c;是衡量一个算法是否高效的重要标准。先纠正一个误区&#xff0c;时间复杂度并不是算法执行的时间&#xff0c;再纠正一个误区&#xff0c;算法不单单指冒泡排序之类的&#xff0c;一个循…

获取期货股票历史数据以及均线策略分析

【数据获取】银河金融数据库&#xff08;yinhedata.com&#xff09;能够获取国内外金融股票、期货历史行情数据&#xff0c;包含各分钟级别。 【搭建策略】均线策略作为一种广泛应用于股票、期货等市场的技术分析方法&#xff0c;凭借其简单易懂、操作性强等特点&#xff0c;深…

CV图像处理小工具——json文件转P格式mask

CV图像处理小工具——json文件转P格式mask import cv2 import json import numpy as np import osdef func(file_path: str) -> np.ndarray:try:with open(file_path, moder, encoding"utf-8") as f:configs json.load(f)# 检查JSON是否包含必要的字段if "…

【专题】2024年中国电商市场研究报告合集PDF分享(附原数据表)

原文链接&#xff1a;https://tecdat.cn/?p37835 在全球电商持续发展的背景下&#xff0c;中国电商市场面临新态势。 增长压力与机遇并存&#xff0c;从综合电商与直播电商发展的放缓&#xff0c;到企业 3C 数码商用品电商采购的趋势&#xff0c;以及零售业拥抱“性价比时代…

校园网站设计怎么做

校园网站设计是一项复杂而又具有挑战性的任务&#xff0c;因为它需要考虑到学校内各种不同的需求和利益。一个成功的校园网站应该能够满足学生、教职员工、家长和管理人员的需求&#xff0c;同时提供清晰、易用且富有吸引力的界面。以下是一些设计校园网站的关键方面&#xff0…

腾讯全文检索引擎 wwsearch 正式开源

背景 企业微信作为典型企业服务系统&#xff0c;其众多企业级应用都需要全文检索能力&#xff0c;包括员工通讯录、企业邮箱、审批、汇报、企业CRM、企业素材、互联圈子等。下图是一个典型的邮件检索场景。 由于过去几年业务发展迅速&#xff0c;后台检索架构面临挑战&#xf…

学霸都在用的秘密武器!盘点3款语音识别转文字软件,学习力MAX!

现在科技这么发达&#xff0c;手写笔记好像越来越不流行了。在这个什么都讲究快的时代&#xff0c;怎么又快又好地记下重要信息&#xff0c;是大家都想要的。正好&#xff0c;现在市面上有很多能把语音转换成文字的工具&#xff0c;它们特别有用&#xff0c;正在慢慢改变我们学…

pipe和pipefd

Linux 中 pipe 的详细介绍 在 Linux 中&#xff0c;pipe 是一个系统调用&#xff0c;用于创建一个管道&#xff0c;这是一种用于进程间通信&#xff08;IPC&#xff09;的机制。管道允许两个进程之间进行单向数据传输&#xff0c;通常是一个进程向管道写入数据&#xff0c;而另…

【机器学习】金融预测 —— 风险管理与股市预测

我的主页&#xff1a;2的n次方_ 在金融领域&#xff0c;机器学习&#xff08;ML&#xff09;已经成为了不可或缺的工具。金融预测&#xff0c;尤其是风险管理和股市预测&#xff0c;涉及海量数据和复杂模式的分析&#xff0c;而这些正是机器学习擅长处理的领域。通过分析历…

什么是矩阵系统,怎么选择矩阵系统,怎么oem贴牌,怎么源码搭建

一、架构设计方面 采用微服务架构 将矩阵系统拆分为多个小型的、独立的服务模块。每个微服务专注于特定的业务功能&#xff0c;如用户管理、内容发布、数据分析等。这样可以独立地开发、部署和扩展每个服务&#xff0c;而不会影响整个系统。例如&#xff0c;当用户量增加导致用…

机器学习与神经网络荣膺诺贝尔物理学奖:跨学科融合的时代来临

近日&#xff0c;2024年诺贝尔物理学奖颁发给了机器学习与神经网络领域的研究者&#xff0c;这一消息犹如一颗重磅炸弹&#xff0c;迅速在全球学术界和科技界引起了轰动和热议。这是诺贝尔物理学奖首次将桂冠授予计算机科学领域的研究者&#xff0c;标志着物理学与计算机科学的…

dvwa:文件包含、文件上传

文件包含 本地文件包含&#xff08;敏感信息泄露&#xff09;和远程文件包含&#xff08;命令执行&#xff09; 本地文件包含一般包含一些本地的敏感文件&#xff0c;如&#xff1a;/etc/passwd或/etc/shadow等 远程文件包含能使得服务器代码执行&#xff0c;如包含黑客vps的…

【纯前端实现xlsx的解析并处理成table需要的格式】

概要 xlsx纯前端导入并解析成json 整体架构流程 xlsx导入并解析成json&#xff0c;并与table中的数据进行对比&#xff0c;根据唯一标识更新对应数据项 技术名词解释 vue2xlsx 技术细节 首先下载xlsx依赖 npm install xlsx --save然后在需要导入xlsx的地方 这里主要用in…

基于模型的强化学习方法4大类灌水范式

我们都知道基于模型的强化学习&#xff0c;就是从数据中学一个环境模型。 举个例子&#xff0c;我们要控制一个马达&#xff0c;输入就是电流&#xff0c;输出就是转速。无模型强化学习就是随机采样&#xff0c;然后从数据中直接学习输入到输出的影射&#xff0c;研究重心在如…

【AAOS】Android Automotive 10模拟器源码下载及编译

源码下载 repo init -u https://android.googlesource.com/platform/manifest -b android-10.0.0_r47 repo sync -c --no-tags --no-clone-bundle 源码编译 source build/envsetup.sh lunch aosp_car_x86_64-userdebug make -j8 运行效果 emualtor Cluster Home Map All …

大模型部署-​Ollama+WebUI

Ollama&#xff08;安装包和安装文档文末领取&#xff01;&#xff09; Ollama 简介 主要特点&#xff1a; 易于使用&#xff1a;它提供了一个简洁的界面和命令行工具&#xff0c;使得用户可以方便地管理和运行不同的大语言模型。 多种模型支持&#xff1a;可以运行多种开源…

ip地址换网就不一样了吗?ip地址会因什么变动而变化

在当今数字化时代&#xff0c;IP地址作为网络设备的唯一标识&#xff0c;扮演着至关重要的角色。然而&#xff0c;对于许多用户来说&#xff0c;IP地址的变动仍然是一个充满疑惑的话题。那么&#xff0c;IP地址换网就真的不一样了吗&#xff1f;本文将深入探讨IP地址变动的因素…