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);
}
}
}