[AttributeUsage(AttributeTargets.Class)]
public class LogAttribute : ContextAttribute
{
#region Constructor
public LogAttribute()
: base("Log")
{
}
#endregion
#region ContextAttribute Overrides
public override void Freeze(Context newContext)
{
}
public override void GetPropertiesForNewContext(System.Runtime.Remoting.Activation.IConstructionCallMessage ctorMsg)
{
ctorMsg.ContextProperties.Add(new LogProperty());
}
public override bool IsContextOK(Context ctx, System.Runtime.Remoting.Activation.IConstructionCallMessage ctorMsg)
{
LogProperty property =
ctx.GetProperty("Log") as LogProperty;
if (property == null)
{
return false;
}
return true;
}
public override bool IsNewContextOK(Context newCtx)
{
LogProperty property =
newCtx.GetProperty("Log") as LogProperty;
if (property == null)
{
return false;
}
return true;
}
#endregion
}
public class LogProperty : IContextProperty, IContributeObjectSink
{
#region IContextProperty Members
public string Name
{
get
{
return "Log";
}
}
public bool IsNewContextOK(Context newCtx)
{
LogProperty property =
newCtx.GetProperty("Log") as LogProperty;
if (property == null)
{
return false;
}
return true;
}
public void Freeze(Context newContext)
{
}
#endregion
#region IContributeObjectSink Members
public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink nextSink)
{
return new LogSink(nextSink);
}
#endregion
}
public class LogSink : IMessageSink
{
#region Data Members
private IMessageSink mNextSink;
private ILog mLog = LogManager.GetLogger("MyLogger");
#endregion
#region Constructor
public LogSink(IMessageSink nextSink)
{
this.mNextSink = nextSink;
}
#endregion
#region IMessageSink Members
public IMessage SyncProcessMessage(IMessage msg)
{
IMethodCallMessage call = msg as IMethodCallMessage;
mLog.DebugFormat("Entering {0}, with parameters {1}",
call.MethodBase.Name,
GetParameters(call));
IMethodReturnMessage result =
mNextSink.SyncProcessMessage(msg) as IMethodReturnMessage;
if (result.Exception != null)
{
mLog.Error("An error occured on " + call.MethodBase.Name,
result.Exception);
}
else
{
mLog.DebugFormat("Exiting {0} with return value: {1}",
result.MethodBase,
result.ReturnValue);
}
return result;
}
public IMessageSink NextSink
{
get
{
return this.mNextSink;
}
}
public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
{
IMessageCtrl rtnMsgCtrl = mNextSink.AsyncProcessMessage(msg, replySink);
return rtnMsgCtrl;
}
private string GetParameters(IMethodCallMessage call)
{
return string.Join
(",",
call.MethodBase.GetParameters().Select((x, i) =>
new { x.Name, Index = i }).
Select(x => x.Name + ":" + call.Args[x.Index]));
}
#endregion
}