Dynamically creating a proxy class

后端 未结 4 1280
深忆病人
深忆病人 2020-11-30 21:39

I am trying to create a proxy class dynamically. I know there are some very good frameworks out there to do this but this is purely a pet project as a learning exercise so

4条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-11-30 21:52

    Have a look at System.Runtime.Remoting.Proxies.RealProxy. You can use this to create an instance that appears to be the target type from the perspective of the caller. RealProxy.Invoke provides a point from which you can simply invoke the target method on the underlying type or perform additional processing before/after the call (logging, for example).

    Here's an example of a proxy that logs to the console before/after each method invocation:

    public class LoggingProxy : RealProxy
    {
        private readonly T _instance;
    
        private LoggingProxy(T instance)
            : base(typeof(T))
        {
            _instance = instance;
        }
    
        public static T Create(T instance)
        {
            return (T)new LoggingProxy(instance).GetTransparentProxy();
        }
    
        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(_instance, 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);
            }
        }
    }
    

    Here is how you would use it:

    IMyInterface intf = LoggingProxy.Create(new MyClass());
    intf.MyProcedure();
    

    The output to console would then be:

    Before invoke: MyProcedure
    Hello World
    After invoke: MyProcedure

提交回复
热议问题