Programming .NET Components

I couple of weeks ago i got a copy of Programming .NET Components… I can only suggest to read it yourself because i found it really good ;) Anyway, in one of the chapters Juval Lowy talks about context and interception (msdnmag article). I got inspired and implemented my own log4net LoggingSink:

public class LoggingSink : IMessageSink
{
 ...

 public IMessage SyncProcessMessage(IMessage msg)
 {
  IMethodMessage methodMessage = msg as IMethodMessage;
  ILog log = LogManager.GetLogger(methodMessage.TypeName);
  log.Debug(methodMessage);

  IMessage message = this.nextSink.SyncProcessMessage(msg);

  IMethodReturnMessage methodReturnMessage = message as IMethodReturnMessage;
  if (methodReturnMessage != null)
  {
   log.Debug(methodReturnMessage);
  }

  return message;
 }
}

I also implemented my own MethodMessageRenderer and MethodReturnMessageRenderer using an ObjectRenderer that was inspired on the ObjectDumper that comes with the LINQ CTP samples

public class MethodReturnMessageRenderer : IObjectRenderer
{
 #region Constructors

 public MethodReturnMessageRenderer()
 {
 }

 #endregion

 #region IObjectRenderer Members

 public void RenderObject(RendererMap rendererMap, object obj, TextWriter writer)
 {
  IMethodReturnMessage methodReturnMessage = obj as IMethodReturnMessage;
  writer.WriteLine("{0}Called: {1}{2}Params:", Environment.NewLine, methodReturnMessage.MethodName, Environment.NewLine);
  ObjectRenderer.RenderObject(methodReturnMessage.Args, writer);
  if (methodReturnMessage.MethodName != ".ctor")
  {
   writer.WriteLine("{0}ReturnValue:", Environment.NewLine);
   ObjectRenderer.RenderObject(methodReturnMessage.ReturnValue, writer);
  }
  if (methodReturnMessage.Exception != null)
  {
   writer.WriteLine("{0}Exception:", Environment.NewLine);
   ObjectRenderer.RenderObject(methodReturnMessage.Exception, writer);
  }
  writer.WriteLine();
 }

 #endregion
}

Adding an [assembly: XmlConfigurator(Watch = true)] attribute to the AssemblyInfo.cs of projects that use log4Net seems the easiest way to get the configuration right. In your configuration you still have to register the IObjectRenderers:

<renderer renderingClass="EndPointTools.MethodReturnMessageRenderer, EndPointTools" renderedClass="System.Runtime.Remoting.Messaging.IMethodReturnMessage, mscorlib"/>

Have a look at the generated log and feel free to download the complete solution: ContextBoundSamples.zip.

Comments are closed.