C# 在执行其他方法之前触发一个方法

C# 在执行其他方法之前触发一个方法,c#,asp.net,asp.net-mvc,C#,Asp.net,Asp.net Mvc,有没有一种方法可以在另一个方法(如触发器)之前调用要执行的方法 类似于指示要执行的方法的属性,如下所示: [OnBefore(MethodToBeExecutedBefore)] public void MethodExecutedNormally() { //method code } 我有一种情况,我需要经常调用check方法,而且大多数情况下,它们都是在花太长时间执行的方法之前执行的。没有内置的方法来实现这个结果,如果您使用依赖项注入机制,那么如果DI框架支持,您可以使用拦截工具

有没有一种方法可以在另一个方法(如触发器)之前调用要执行的方法

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

[OnBefore(MethodToBeExecutedBefore)]
public void MethodExecutedNormally()
{
    //method code
}

我有一种情况,我需要经常调用check方法,而且大多数情况下,它们都是在花太长时间执行的方法之前执行的。

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


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

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


如果您想降低级别,还可以在运行时使用创建派生类,该派生类使用特定属性覆盖方法,该属性调用您想要的任何额外功能,但这更困难。

您所说的是AOP或

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


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

你所说的是所谓的AOP或

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


至于外部工具,是.NET的事实上标准的AOP后置编译器,但它不是免费的(至少不是真正的使用,有一个免费的版本你可能想尝试,也许它对你的用例足够了)。 您可以创建一个接口和一些基类来处理事件,然后让长时间运行的类从中继承。订阅事件并相应处理:

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委托void BeforeMethodExecutionHandler(ILongRunningWithEvents发送方、targets args、字符串调用方);
公共接口ILongRunningWithEvents
{
事件BeforeMethodExecutionHandler OnBeforeMethodExecution;
}
公共类LongRunningClass:ILongRunningWithEvents
{
私有BeforeMethodExecutionHandler\u onBeforeMethodExecution;
公共事件BeforeMethodExecutionHandler OnBeforeMethodExecution
{
添加{onBeforeMethodExecution+=value;}
删除{onBeforeMethodExecution-=value;}
}   
受保护的void RaiseOnBeforeMethodExecution(目标e,[CallerMemberName]字符串调用者=null)
{
_onBeforeMethodExecution?.Invoke(this,e,调用者);
}
}
公共类具体运行类:龙运行类
{
public void somelonglunningmethod()
{
RaiseOnBeforeMethodExecution(新样本参数(“开始”);
//这里是该方法的代码
}
}
公共类样本
{
公共样本参数(字符串消息)
{
消息=消息;
}
公共字符串消息{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);
}
publicstaticvoidtestlonglunning()
{
ConcreteRunningClass concrete=新的ConcreteRunningClass();
concrete.onbeforethodexecution+=concrete\u onbeforethodexecution;
具体的。一些长期的方法();
}
私有静态void Concrete_OnBeforeMethodExecution(ILongRunningWithEvents发送方、SampleArgs args args、字符串调用方)
{
Console.WriteLine(“{0}:{1}”,调用方??“未知”,args.Message);
}
消息
SomeLongRunningMethod:开始将在长时间运行的方法执行之前输出

您可以将呼叫者名称添加到参数中。为了说明这一点,我很快就把它写了出来


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

< P>我认为您应该考虑事件驱动的方法。

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

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委托void BeforeMethodExecutionHandler(ILongRunningWithEvents发送方、targets args、字符串调用方);
公共接口ILongRunningWithEvents
{
事件BeforeMethodExecutionHandler OnBeforeMethodExecution;
}
公共类LongRunningClass:ILongRunningWithEvents
{
私有BeforeMethodExecutionHandler\u onBeforeMethodExecution;
公共事件BeforeMethodExecutionHandler OnBeforeMethodExecution
{
添加{onBeforeMethodExecution+=value;}
删除{onBeforeMethodExecution-=value;}
}   
受保护的void RaiseOnBeforeMethodExecution(目标e,[CallerMemberName]字符串调用者=null)
{
_onBeforeMethodExecution?.Invoke(this,e,调用者);
}
}
公共类具体运行类:龙运行类
{
public void somelonglunningmethod()
{
RaiseOnBeforeMethodExecution(新样本参数(“开始”);
//这里是该方法的代码
}
}
公共类样本
{
公共样本参数(字符串消息)
{
消息=消息;
}
公共字符串消息{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);
}
publicstaticvoidtestlonglunning()
{
ConcreteRunningClass concrete=新的ConcreteRunningClass();
concrete.onbeforethodexecution+=concrete\u onbeforethodexecution;
具体的。一些长期的方法();
}
专用静态空心混凝土\u OnBeforeMethodExecuti