using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;
using
System.Runtime.Remoting.Proxies;
namespace
TTester
{
/
public class Calculator : MarshalByRefObject
{
private Calculator() { }
public static Calculator CreateInstance()
{
MessageChainProxy realProxy = new MessageChainProxy(new Calculator());
realProxy.AppendSinkType(typeof(LogAspect));
Object transparentProxy = realProxy.GetTransparentProxy();
return (Calculator)transparentProxy;
}
public int Add(int x, int y)
{
return x + y;
}
}
/
public class MessageChainProxy : RealProxy
{
private class TerminatorSink : IMessageSink
{
private MarshalByRefObject m_target;
public TerminatorSink(MarshalByRefObject target)
{
this.m_target = target;
}
#region
IMessageSink Members
public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
{
throw new Exception("The method or operation is not implemented.");
}
public IMessageSink NextSink
{
get { return null; }
}
public IMessage SyncProcessMessage(IMessage msg)
{
return RemotingServices.ExecuteMessage(m_target, msg as IMethodCallMessage);
}
#endregion
}
private MarshalByRefObject m_target;
private IMessageSink headSink;
public MessageChainProxy(MarshalByRefObject target)
: base(target.GetType())
{
this.m_target = target;
headSink = new TerminatorSink(m_target);
}
public override IMessage Invoke(IMessage msg)
{
return headSink.SyncProcessMessage(msg);
}
public void AppendSinkType(Type sinkType)
{
object[] ctorArgs = new object[] { headSink };
IMessageSink newSink = (MessageSinkBase)Activator.CreateInstance(sinkType, ctorArgs);
headSink = newSink;
}
}
/
public abstract class MessageSinkBase : IMessageSink
{
private readonly IMessageSink m_nextSink;
public MessageSinkBase(IMessageSink nextSink)
{
m_nextSink = nextSink;
}
#region
IMessageSink Members
public virtual IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
{
return m_nextSink.AsyncProcessMessage(msg, replySink);
}
public IMessageSink NextSink
{
get { return m_nextSink; }
}
public abstract IMessage SyncProcessMessage(IMessage msg);
#endregion
}
//
public class LogAspect : MessageSinkBase
{
public LogAspect(IMessageSink nextSink)
: base(nextSink)
{
}
public override IMessage SyncProcessMessage(IMessage msg)
{
IMethodCallMessage callMsg = msg as IMethodCallMessage;
DateTime callTime = DateTime.Now;
IMessage returnMsg = NextSink.SyncProcessMessage(msg);
DateTime retTime = DateTime.Now;
IMethodReturnMessage retMsg = returnMsg as IMethodReturnMessage;
TimeSpan tspan = callTime.Subtract(retTime);
string[] strs = callMsg.TypeName.Split(new char[] { ',', '.' });
string clsName = null;
if (strs.Length >= 2)
{
clsName = strs[1];
}
Console.WriteLine("[" + callTime + "] " +
clsName +
"." +
callMsg.MethodName +
"(" +
callMsg.InArgs[0] +
"," +
callMsg.InArgs[1] +
") " +
"-(" +
tspan.TotalMilliseconds * 1000000 +
"ns)-> " +
retMsg.ReturnValue
);
return returnMsg;
}
}
}