Can I conditionally control method calls at runtime with attributes?

Asked
Viewd1496

1

The Conditional Attribute in .NET allows you to disable the invocation of methods at compile time. I am looking for basically the same exact thing, but at run time. I feel like something like this should exist in AOP frameworks, but I don't know the name so I am having trouble figuring out if it is supported.

So as an example I'd like to do something like this

[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;
}

So where ever in code there is a call to the M method, it would first call RuntimeConditional and pass in Bob to determine if M should be executed.

  • In your example, What kind of code would make M execute? What kind of code would make it not execute, and what would you expect to happen instead?

    StoborAugust 07, 2009 01:46
  • You could simply throw an exception in the OnEntry override of the Trace attribute. Not quite what you were looking for, but it will stop your method from executing.

    Yuriy FaktorovichAugust 07, 2009 05:37
  • I want to achieve the same behavior as the regular Conditional attribute. Throwing an exception is going would break that behavior.

    BobAugust 07, 2009 12:22
  • The RuntimeConditional Method would control if it would execute. Right now Bob is hardcoded, so it will always execute. The string Bob in the RuntimeConditional Method would be replaced with some code to pull from a config file/database field to see if the method should be called or not.

    BobAugust 07, 2009 01:48

2 个答案

5

您实际上可以使用 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属性。

  • Cool. Though I just realised i mucked up the logic - you want FlowBehaviour.Return if the condition is not met.

    Nader ShirazieAugust 07, 2009 11:24
0

我相信这将是您描述的一种非常简单的方式:

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

谢谢

  • Yeah that isn’t using attributes though.

    BobAugust 07, 2009 01:33