概述:.NET 远程代理的使用

以下 Demo 演示如何在 .Net 跨 AppDomain 情况下通过代理的方式创建对象。

 
    public class TestProxy : RealProxy
    {
        private IEngineProxy _target;
 
        public TestProxy(Type classToProxy, IEngineProxy target)
          : base(classToProxy)
        {
            _target = target;
        }
 
        public override IMessage Invoke(IMessage msg)
        {
            var methodCall = (IMethodCallMessage)msg;
            var method = (MethodInfo)methodCall.MethodBase;
 
            try
            {
                Console.WriteLine("Before invoke: " + method.Name);
                var result = method.Invoke(_target, methodCall.InArgs);
                Console.WriteLine("After invoke: " + method.Name);
                return new ReturnMessage(result, null, 0, methodCall.LogicalCallContext, methodCall);
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception: " + e);
                if (e is TargetInvocationException && e.InnerException != null)
                {
                    return new ReturnMessage(e.InnerException, msg as IMethodCallMessage);
                }
 
                return new ReturnMessage(e, msg as IMethodCallMessage);
            }
        }
    }
 
    public class MyRealProxy<T> : RealProxy where T : class
    {
        private T _target;
 
        public MyRealProxy(T target)
          : base(typeof(T))
        {
            _target = target;
        }
 
        public static T Create(T instance)
        {
            return (T)new MyRealProxy<T>(instance).GetTransparentProxy();
        }
        public override IMessage Invoke(IMessage msg)
        {
            try
            {
                IMethodCallMessage call = msg as IMethodCallMessage;
                var args = call.Args;
                var interfaces = call.GetType().GetInterfaces();
                object returnValue = typeof(MarshaleLoader).InvokeMember(call.MethodName,
                    BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance,
                    null,
                    _target,
                    args);
                return new ReturnMessage(returnValue, args, args.Length, call.LogicalCallContext, call);
            }
            catch (Exception e)
            {
                throw e;
            }
        }
    }