向多个目标类中的方法调用注入外部参数

本文关键字:调用 方法 注入 外部 参数 目标 | 更新日期: 2023-09-27 18:07:35

我有许多类,在各种方法中调用Trace.WriteLine("LogSomethingClassSpecific")。现在,我希望其中一些类像这样调用它们所有的Trace。WriteLine("LogSomethingClassSpecific"、"CategoryA")

但是!我想从单个分类器类外部实现这一点;而不必查找和修改每个特定类中的每个Trace调用。

<<h2>示例架构/h2>
  • Class1,Class2,Class3,可以或不可以使用Trace调用

  • 单独的ControllerClass,它使所有现有的跟踪调用,比如Class2和Class3被调用,并添加参数"CategoryA"。

这是如何实现的?

可能使用一些属性与面向方面编程(AOP)库相结合吗?如。控制类可以指定目标类:

[assembly: Categorizer("CategoryA", AttributeTargetTypes = "Namespace.ClassB")]

然后拦截所有Trace。使用PostSharp调用WriteLine

但我不知道一种方法来提取调用上下文,以确定调用类是否已被标记为包括"CategoryA"?

或者是否有其他方法来实现这一目标?

感谢所有的想法。

向多个目标类中的方法调用注入外部参数

有几种方法可以做到这一点,但我假设你在if/else结构中调用Trace所以这里是你如何去做你所要求的(至少,我认为你所要求的)

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using PostSharp.Aspects;
    using System.Diagnostics;
    [assembly: ConsoleApplication2.TraceIntercept(AttributeTargetAssemblies = "System", AttributeTargetTypes = "System.Diagnostics.Trace")]
    namespace ConsoleApplication2
    {
        class Program
        {
            static void Main(string[] args)
            {
                ExampleA ex = new ExampleA();
                ex.Method1();
                Console.ReadKey();
            }
        }
        public class ExampleA
        {
            public void Method1()
            {
                Trace.Write("Test");
            }
        }
[Serializable]
    [TraceIntercept(AttributeExclude = true)]
    public class TraceIntercept : MethodInterceptionAspect
    {
        private bool addArgument;
        private string typeName = string.Empty;
        public override void OnInvoke(MethodInterceptionArgs args)
        {
            CheckInvocationPoint();
            if (addArgument)
            {
                //Do work. Change arguments, etc.
            }
            args.Proceed(); // Proceed with Trace
        }
        private void CheckInvocationPoint()
        {
            if (string.IsNullOrEmpty(this.typeName))
            {
                StackTrace s = new StackTrace();
                StackFrame f = s.GetFrame(2);
                string className = f.GetMethod().DeclaringType.Name;
                if (classsName.Equals("ExampleA"))
                {
                    addArgument = true;
                }
            }
        }
    }
}

这将拦截对System.Diagnostics.Trace方法的调用,并将调用TraceIntercept。方法,您可以在其中操作Trace调用。工作方式是PostSharp将简单地替换对Trace的调用。使用对方面的调用来编写。

Edit:据我所知,没有办法获取目标方法的实际调用点。这意味着您必须在运行时进行一些反射。我已经更新了代码以使用堆栈跟踪。您只需要执行一次(每个类型),因为方面生命周期将是每个类型而不是每个实例,所以您只需要执行一次。我不会这样做,但我认为这是为了调试的目的。