【问题标题】:Can I conditionally control method calls at runtime with attributes?我可以在运行时使用属性有条件地控制方法调用吗?
【发布时间】:2009-08-07 01:22:33
【问题描述】:

.NET 中的Conditional Attribute 允许您在编译时禁用方法的调用。我正在寻找基本相同的东西,但在运行时。我觉得这样的东西应该存在于 AOP 框架中,但我不知道它的名称,所以我无法确定它是否受支持。

作为一个例子,我想做这样的事情

[RuntimeConditional("Bob")]
public static void M() {
   Console.WriteLine("Executed Class1.M");
}

//.....

//Determines if a method should execute.
public bool RuntimeConditional(string[] conditions) {
    bool shouldExecute = conditions[0] == "Bob";

    return shouldExecute;
}

因此,无论何时在代码中调用 M 方法,它都会首先调用 RuntimeConditional 并传入 Bob 以确定是否M 应该被执行。

【问题讨论】:

  • 在你的例子中,什么样的代码会让 M 执行?什么样的代码会使其无法执行,而您希望发生什么?
  • RuntimeConditional 方法将控制它是否会执行。现在 Bob 是硬编码的,所以它会一直执行。 RuntimeConditional Method 中的字符串 Bob 将被替换为从配置文件/数据库字段中提取的一些代码,以查看是否应该调用该方法。
  • 您可以简单地在 Trace 属性的 OnEntry 覆盖中抛出异常。不是你想要的,但它会阻止你的方法执行。
  • 我想实现与常规条件属性相同的行为。抛出异常会破坏这种行为。

标签: c# .net aop


【解决方案1】:

您实际上可以使用PostSharp 来做您想做的事。

这是一个您可以使用的简单示例:

[Serializable]
public class RuntimeConditional : OnMethodInvocationAspect
{
    private string[] _conditions;

    public RuntimeConditional(params string[] conditions)
    {
        _conditions = conditions;
    }

    public override void OnInvocation(MethodInvocationEventArgs eventArgs)
    {
        if (_conditions[0] == "Bob") // do whatever check you want here
        {
            eventArgs.Proceed();
        }
    }
}

或者,由于您只是在查看方法执行“之前”,您可以使用OnMethodBoundaryAspect

[Serializable]
public class RuntimeConditional : OnMethodBoundaryAspect 
{
    private string[] _conditions;

    public RuntimeConditional(params string[] conditions)
    {
        _conditions = conditions;
    }

    public override void OnEntry(MethodExecutionEventArgs eventArgs)
    {
        if (_conditions[0] != "Bob")
        {
            eventArgs.FlowBehavior = FlowBehavior.Return; // return immediately without executing
        }
    }
}

如果你的方法有返回值,你也可以处理它们。 eventArgs 有一个可设置的 returnValue 属性。

【讨论】:

  • 酷。虽然我刚刚意识到我搞砸了逻辑 - 如果条件不满足,你想要 FlowBehaviour.Return。
  • 这很好,但是是否可以在不依赖第三方的情况下使用简单的属性来做到这一点?我有一个项目,让第三方图书馆获得批准是一个漫长的过程。我希望有一些简单快速的东西,你可以说如果这个变量是真的执行方法 else 简单地返回。
【解决方案2】:

我相信这将是一种非常简单的方式来做你描述的事情:

public static void M() 
{
   if (RuntimeConditional("Bob"))
   {
       Console.WriteLine("Executed Class1.M");
   }
}

谢谢

【讨论】:

  • 是的,虽然没有使用属性。
猜你喜欢
  • 1970-01-01
  • 2013-08-20
  • 2011-11-23
  • 2018-09-27
  • 1970-01-01
  • 2012-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多