c# 根据日志中的方法信息,反射再次执行相关方法

场景:

在实际的项目中,会遇到与第三方的接口互调,在这样的场景下,日志显得尤为重要。

有这样一种情况,就是在请求第三方接口后,需要将请求的结果进行过滤处理,再持久化,这就需要服务中提供相关的服务方法来执行,如果执行异常,或是有错误,希望通过相关的后台界面,再次执行时,就可以将服务方法的相关信息记录,通过反射再次调用。

方法类型

 public class ReflectionMethodInfo
    {
        public string AssemblyInfo { get; set; }

        public string TypeInfo { get; set; }

        public string MethodInfo { get; set; }

        public Type[] ParameterTypeInfo { get; set; }

        public object[] ParameterInfo { get; set; }
    }

记录日志

public class TxtHelper
    {
        static string txtPath
        {
            get
            {
                return AppDomain.CurrentDomain.BaseDirectory + "log.txt";
            }
        }

        public static void writeTxt(object txt)
        {
            var text = string.Empty;
            if (typeof(ReflectionMethodInfo).IsInstanceOfType(txt))
            {
                text = "【reflection】" + Newtonsoft.Json.JsonConvert.SerializeObject(txt) + "【reflection】";
            }
            else
            {
                text = txt.ToString();
            }

            System.IO.File.AppendAllText(txtPath, text);
            System.IO.File.AppendAllText(txtPath, Environment.NewLine);
        }

        public static void writeMethod(Assembly assembly, MethodBase methodBase, object[] parameterInfo)
        {
            var reflectionMethodInfo = new ReflectionMethodInfo()
            {
                AssemblyInfo = assembly.FullName,
                TypeInfo = methodBase.DeclaringType.FullName,
                MethodInfo = methodBase.Name,
                ParameterTypeInfo = methodBase.GetParameters().Select(p => p.ParameterType).ToArray(),
                ParameterInfo = parameterInfo
            };
            TxtHelper.writeTxt(reflectionMethodInfo);

        }
    }

调用记录方法

public void ParameterMethod(string parameter, TestParameters testParameters)
        {
            this.name = parameter;

            TxtHelper.writeTxt($"NetReflection.ParameterMethod({parameter},{testParameters}) 【EXEC】");

            TxtHelper.writeMethod(Assembly.GetExecutingAssembly(), MethodBase.GetCurrentMethod(), new object[] { parameter, testParameters });
        }

 反射执行

static object DynamicExecMethod(string methodInfo)
        {
            var methodInfoObj = JsonConvert.DeserializeObject<ReflectionMethodInfo>(methodInfo);

            if (methodInfoObj == null)
            {
                Console.WriteLine("methodInfoObj is null");
                return null;
            }

            // 加载程序集
            var assembly = Assembly.Load(methodInfoObj.AssemblyInfo);

            // 获取类型
            var type = assembly.GetType(methodInfoObj.TypeInfo);

            // 创建实例 , 此方式要求实例类型必须有无参构造函数
            var instance = Activator.CreateInstance(type);

            // 加载方法
            var method = type.GetMethod(methodInfoObj.MethodInfo, methodInfoObj.ParameterTypeInfo);

            // 创建参数类型信息,JObject 转换成指定的参数类型
            var newParameters = new List<object>();
            var parameters = methodInfoObj.ParameterInfo;
            var declareParameters = method.GetParameters();
            var parameterIndex = 0;
            foreach (var parameter in declareParameters)
            {
                var parameterType = parameter.ParameterType;
                var newParameter = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(parameters[parameterIndex]), parameterType);
                newParameters.Add(newParameter);
                parameterIndex++;
            }

            // 执行方法
            var returnValue = method.Invoke(instance, newParameters.ToArray());

            return returnValue;
        }

数据库表

CREATE TABLE [dbo].[Application_Log](
    [Id] [uniqueidentifier] NOT NULL,
    [SerialNumber] [varchar](50) NULL,
    [Url] [varchar](4000) NULL,
    [Body] [nvarchar](max) NULL,
    [Result] [nvarchar](max) NULL,
    [Method] [nvarchar](max) NULL,
    [Mark] [nvarchar](max) NULL,
    [State] [bit] NOT NULL,
    [Action] [varchar](50) NOT NULL,
    [Type] [varchar](50) NULL,
    [CreateTime] [datetime] NOT NULL,
    [LogicDeleteFlag] [bit] NOT NULL,
 CONSTRAINT [PK_Api_Log] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'调用/请求/同步等操作接口' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Application_Log', @level2type=N'COLUMN',@level2name=N'Url'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'请求Body' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Application_Log', @level2type=N'COLUMN',@level2name=N'Body'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'请求结果' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Application_Log', @level2type=N'COLUMN',@level2name=N'Result'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'程序代码中相关方法信息,主要目的是为处理拉取类时,可以再次拉取。(拉取信息不仅仅是请求,还需要处理请求的结果)' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Application_Log', @level2type=N'COLUMN',@level2name=N'Method'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'其它备注说明' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Application_Log', @level2type=N'COLUMN',@level2name=N'Mark'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'请求状态 成功、失败' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Application_Log', @level2type=N'COLUMN',@level2name=N'State'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'具体操作,如第三方调用,拉取日志,拉取轨迹' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Application_Log', @level2type=N'COLUMN',@level2name=N'Action'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'本次请求类型:ThirdRequest(第三方请求我方接口)、PullThird(拉取/请求 第三方信息)、PushThird(同步/推送 信息到第三方)' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Application_Log', @level2type=N'COLUMN',@level2name=N'Type'
GO
原文地址:https://www.cnblogs.com/challengesoflife/p/14544587.html