在其他方法执行之前触发方法

时间:2018-02-13 15:50:45

标签: c# asp.net asp.net-mvc

有没有办法在另一个方法之前调用一个方法,比如一个触发器?

类似于指示要执行的方法的属性,如:

arrayCount() {
  let count = 0;
  let sliced = this.state.data.slice();
  this.setState({
    data: sliced[count++],
  })
}

componentDidMount() {
  let timer = setInterval(this.arrayCount.bind(this), 1000);
}

我遇到的情况是我需要经常调用check方法,并且大部分时间都是在需要很长时间执行的方法之前。

3 个答案:

答案 0 :(得分:1)

没有内置的方法来实现这个结果,如果你使用依赖注入机制,你可以使用拦截工具,如果DI框架支持这个。 (例如:UnityNInject

如果你想进入低级别,你也可以使用Reflection.Emit在运行时创建一个派生类,它会覆盖具有调用你想要的任何额外功能的特定属性的方法,但这更难。

答案 1 :(得分:1)

您所谈论的内容称为AOP或Aspect Oriented Programming

C#中没有内置选项。虽然属性存在,但没有机制可以对它们采取任何操作。您总是需要一段代码来读取这些属性然后执行某些操作。属性本身只是元数据和标记。

就外部工具而言,Postsharp是.NET的事实上的标准AOP后编译器,但它不是免费的(至少不是真正使用的,有一个免费版本,你可以想试试,也许它对你的用例来说已经足够了。)

答案 2 :(得分:1)

我认为你应该考虑一种事件驱动的方法。

您可以创建一个接口和一些基类来处理事件,然后让您的长时间运行的类继承它。订阅活动并相应处理:

public delegate void BeforeMethodExecutionHandler<TArgs>(ILongRunningWithEvents<TArgs> sender, TArgs args, string caller);
public interface ILongRunningWithEvents<TArgs>
{
    event BeforeMethodExecutionHandler<TArgs> OnBeforeMethodExecution;
}

public class LongRunningClass<TArgs> : ILongRunningWithEvents<TArgs>
{
    private BeforeMethodExecutionHandler<TArgs> _onBeforeMethodExecution;
    public event BeforeMethodExecutionHandler<TArgs> OnBeforeMethodExecution
    {
        add { _onBeforeMethodExecution += value; }
        remove { _onBeforeMethodExecution -= value; }
    }   
    protected void RaiseOnBeforeMethodExecution(TArgs e, [CallerMemberName] string caller = null)
    {
        _onBeforeMethodExecution?.Invoke(this, e, caller);
    }
}

public class ConcreteRunningClass : LongRunningClass<SampleArgs>
{
    public void SomeLongRunningMethod()
    {
        RaiseOnBeforeMethodExecution(new SampleArgs("Starting!"));
        //Code for the method here
    }
}

public class SampleArgs
{
    public SampleArgs(string message)
    {
        Message = message;
    }

    public string Message { get; private set; }
}

样本用法:

 public static void TestLongRunning()
 {
     ConcreteRunningClass concrete = new ConcreteRunningClass();
     concrete.OnBeforeMethodExecution += Concrete_OnBeforeMethodExecution;
     concrete.SomeLongRunningMethod();
 }

 private static void Concrete_OnBeforeMethodExecution(ILongRunningWithEvents<SampleArgs> sender, SampleArgs args, string caller)
{
    Console.WriteLine("{0}: {1}", caller ?? "unknown", args.Message);
}

在长时间运行的方法执行之前,将输出消息SomeLongRunningMethod: Starting!

您可以将调用者名称添加到args。我快速地说明了这一点。

更新:我看到你为ASP.NET MVC添加了标签。这个概念仍然适用于控制器,因为控制器只是类。