アプリケーションの定型コードを短くしたい (1)
05/29/2011

ShortReflAttr.OnPropertyChangedCallAttribute

using System;
using System.Reflection;
using System.Collections.Generic;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Activation;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Services;

namespace CodeCompress.ShortReflAttr
{
    [AttributeUsage(AttributeTargets.Class)]
    public class OnPropertyChangedCallAttribute : ProxyAttribute 
    {
        public override MarshalByRefObject CreateInstance(Type serverType)
        {
            MarshalByRefObject target = base.CreateInstance(serverType);

            RealProxy proxy = new OnPropertyChangedCallProxy(target, serverType);

            return proxy.GetTransparentProxy() as MarshalByRefObject;
        }
    }

    public class OnPropertyChangedCallProxy : RealProxy
    {
        private readonly MarshalByRefObject _target;

        public OnPropertyChangedCallProxy(MarshalByRefObject target, Type t) : base(t)
        {
            _target = target;
        }

        public override IMessage Invoke(IMessage msg)
        {
            if (msg is IConstructionCallMessage)
            {
                RemotingServices.GetRealProxy(_target).InitializeServerObject((IConstructionCallMessage)msg);
                return EnterpriseServicesHelper.CreateConstructionReturnMessage((IConstructionCallMessage)msg, (MarshalByRefObject)this.GetTransparentProxy());
            }

            IMethodMessage mm = (IMethodMessage)msg;

            if (mm.MethodName.StartsWith("set_"))
            {
                return ExecuteSetter(mm);
            }
            else if (mm.MethodName.StartsWith("get_"))
            {
                return ExecuteGetter(mm);
            }
            else
            {
                return RemotingServices.ExecuteMessage(_target, (IMethodCallMessage)mm);
            }
        }

        private IMethodReturnMessage ExecuteSetter(IMethodMessage mm)
        {
            string propertyName = mm.MethodName.Substring(4);

            MethodInfo mi = _target.GetType().GetMethod("SetPropValue", BindingFlags.Instance | BindingFlags.NonPublic);

            object[] args = new object[3] { propertyName, mm.Args[0], _target };
            mi.Invoke(_target, args);

            return new ReturnMessage(null, null, 0, mm.LogicalCallContext, (IMethodCallMessage)mm);
        }

        private IMethodReturnMessage ExecuteGetter(IMethodMessage mm)
        {
            string propertyName = mm.MethodName.Substring(4);

            MethodInfo mi = _target.GetType().GetMethod("GetPropValue", BindingFlags.Instance | BindingFlags.NonPublic);

            object[] args = new object[2] { propertyName, _target };
            object ret = mi.Invoke(_target, args);

            return new ReturnMessage(ret, null, 0, mm.LogicalCallContext, (IMethodCallMessage)mm);
        }

    }
}

Top of Site
Copyright (c) 2011 Takao Tamura