如何将回调添加到webform项目

时间:2015-04-14 13:44:32

标签: c# vb.net callback delegates

我想为对象的所有方法添加一个公共回调函数。我找到了this SO question,但在那个方法中,我将不得不修改该类的每个功能。我想定义一些beforeFilter方法,在每次方法调用之前都会被触发。我知道我可以使用Action delegates,但我不知道如何。

更新:举个例子,我想要的是这样的

Class MyClass

    Sub MyCallback
        'callback code...
    End Sub

    'Rest of tyhe code

End Class

正如您所看到的,理想情况是添加一个简单(或多个)方法以在所有其他方法之前进行三重处理。也许有一些基类或界面,我不知道(这就是我要求的原因)。

我认为可能存在的其他选项是克隆对象并定义新类,而不是将代码添加到现有类中。因此Class使用Object来访问Type

中的方法
Class NewClass

     Sub AddCallback(Obj As Object, Callback As Action)
          'Add the callback here
     End Sub
End Class

我只是猜测,也许我的一些选择甚至是不可行的,所以请帮助我这个

最贴近的方法

我现在拥有的是这种方法

Sub RunWithCallback(beforFilter As Action, f As Action)

    beforeFilter()
    f()

End Sub

(这意味着RunWithCallback使用ActionFunc个委托来管理子和函数的大量重载,具有不同数量的参数)这个,我必须运行这个Sub而不是调用任何Object方法(传递ByRef参数来捕获函数中的返回值)。像这样的东西

Public Sub DoNothing()
    Debug.WriteLine("Callback working!")
End Sub

Public Sub BeforeFilter()
    Debug.WriteLine("Testing callback...")
End Sub

'To run the above function    
RunWithCallback(AddressOf BeforeFilter, AddressOf DoNothing)

我认为应该有一个更好的解决方案,允许避免调用相同的子,并避免重载,对象类的某种动态扩展方法

2 个答案:

答案 0 :(得分:1)

以下是代表如何工作以及如何使用它们的示例:

public class MyClass
{
    // MyDelegate callback holder
    private MyDelegate _myDelegate;

    // Singleton holder
    private static volatile MyClass _instance;

    ///<summary>
    /// Instance property
    ///</summary>
    public static MyClass Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new MyClass();
            }
            _instance.MyCallbacks(_instance.MyDelegateCallback, _instance.MyDelegateCallback1);
            return _instance;
        }
    }

    ///<summary>
    /// Instance multi-callback caller
    ///</summary>
    ///<param name="callbacks">calbacks to call</param>
    ///<returns>MyClass</returns>
    public static MyClass Instance(params MyDelegate[] callbacks)
    {
        if (_instance == null)
        {
            _instance = new MyClass();
        }
        _instance.MyCallbacks(callbacks);
        return _instance;
    }

    ///<summary>
    /// MyClass constructor
    ///</summary>
    private MyClass()
    {
        // Define the callback
        MyDelegate = MyDelegateCallback;
    }

    ///<summary>
    /// MyDelegate property, here u can change the callback to any function which matches the structure of MyDelegate 
    ///</summary>
    public MyDelegate MyDelegate
    {
        get
        {
            return _myDelegate;
        }
        set
        {
            _myDelegate = value;
        }
    }

    ///<summary>
    /// Call all given callbacks
    ///</summary>
    ///<param name="callbacks">callbacks u want to call</param>
    public void MyCallbacks(params MyDelegate[] callbacks)
    {
        if (callbacks != null)
        {
            foreach (MyDelegate callback in callbacks)
            {
                if (callback != null)
                {
                    callback.Invoke(null);
                }
            }
        }
    }

    ///<summary>
    /// RunTest, if u call this method the defined callback will be raised
    ///</summary>
    public void RunTest()
    {
        if (_myDelegate != null)
        {
            _myDelegate.Invoke("test");
        }
    }

    ///<summary>
    /// MyDelegateCallback, the callback we want to raise
    ///</summary>
    ///<param name="obj"></param>
    private void MyDelegateCallback(object obj)
    {
        System.Windows.MessageBox.Show("Delegate callback called!");
    }

    ///<summary>
    /// MyDelegateCallback1, the callback we want to raise
    ///</summary>
    ///<param name="obj"></param>
    private void MyDelegateCallback1(object obj)
    {
        System.Windows.MessageBox.Show("Delegate callback (1) called!");
    }
}

///<summary>
/// MyDelegate, the delegate function
///</summary>
///<param name="obj"></param>
public delegate void MyDelegate(object obj);

我更新了我的答案,看看MyCallbacks(params MyDelegate[] callbacks)。它会调用与MyDelegate结构相匹配的不同回调。
编辑:
添加了MyClass.Instance&amp; MyClass.Instance(params MyDelegate[] callbacks)

答案 1 :(得分:1)

你有没有考虑过使用Aspect库?直到你的问题,似乎你真的可以用这种方法解决你的问题。

例如,您可以在此处使用PostSharp library,只需派生OnMethodBoundaryAspect class,并处理四个可用的主要事件:

或另外两个:

  • 的onResume
  • OnYield

或其中任何一个。简单的架构是:

int MyMethod(object arg0, int arg1)
{
    OnEntry();
    try
    {
        // YOUR CODE HERE 
        OnSuccess();
        return returnValue;
    }
    catch ( Exception e )
    {
        OnException();
    }
    finally
    {
        OnExit();
    }
}

因此您可以轻松调用Callback函数(并且可以在OnSuccess方法中提取运行时传递的参数:

public override void OnSuccess(MethodExecutionArgs args)
{
    CallBack(GetValueYouNeed(args));
}

PostSharp的简单版本是一个免费许可证,并且有很好的文档记录,因此我强烈建议您研究这种方法。