拦截方法请求和更改参数值

时间:2016-04-05 07:49:37

标签: c#

我能够创建以下示例:

ObservableClass

public class ObservableClass : MarshalByRefObject
{
    public int DoSomething(int id, params string[] names)
    {
        return 1 + names.Length;
    }

    public int DoSomethingElse(int id, params string[] names)
    {
        return 1 + names.Length;
    }
}

拦截

public class Interceptor : RealProxy
{
    private readonly object _target;

    public Interceptor(object target) : base(target.GetType()) { _target = target; }

    public override IMessage Invoke(IMessage msg)
    {
        var methodCall = msg as IMethodCallMessage;
        return methodCall != null ? HandleMethodCall(methodCall) : null;
    }

    private IMessage HandleMethodCall(IMethodCallMessage methodCall)
    {
        try
        {
            var newArgs = methodCall.InArgs;
            if (methodCall.MethodName == "DoSomething")
            {
                for (var i = 0; i < newArgs.Length; i++)
                {
                    if (methodCall.GetArgName(i) == "names")
                    {
                        newArgs[i] = new string[] { "a1", "a2", "a3", "a4" };
                    }
                }
            }
            var result = methodCall.MethodBase.Invoke(_target, newArgs);
            return new ReturnMessage(result, null, 0, methodCall.LogicalCallContext, methodCall);
        }
        catch (TargetInvocationException invocationException)
        {
            var exception = invocationException.InnerException;
            return new ReturnMessage(exception, methodCall);
        }
    }

    public static T Wrap<T>(T target) where T : MarshalByRefObject
    {
        return (T)new Interceptor(target).GetTransparentProxy();
    }
}

通过以下方式调用它:

var temp = Interceptor.Wrap(new ObservableClass());
var doSomethingRes = temp.DoSomething(1, "a", "b", "c");
var doSomethingElseRes = temp.DoSomethingElse(1, "a", "b", "c");

输出:doSomethingRes = 5,doSomethingElseRes = 4.

这是有效的,但经过一些研究后,我认为使用 MarshalByRefObject 和远程 RealProxy 对我的实际应用场景来说将是非常昂贵的。

我想知道我还有什么其他选择(轻盈和良好的表现)可以做出类似的东西吗?

1 个答案:

答案 0 :(得分:0)

是.net Remoting非常慢。如果您需要高性能的东西 - 您可以使用动态代理。

Castle Windsor支持dynamic proxiesinterception,可以为您提供帮助。