When writing server-side sinks, it's important to remember that order matters when declaring your sinks. For example, consider the following block in a config file:
<serverProviders>
<provider type="LoggingSink.ServerSinkLoggerProvider, LoggingSink" />
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
The problem here is that if ServerSinkLoggerProvider is a class that implements IServerChannelSink, the requestMsg parameter will be null in the ProcessMessage method. If you reverse the ordering of the 2 lines (i.e. put the formatter first), everything works fine.
This is by design, and due to the chaining of sinks that occurs in .NET Remoting. In the first case, the formatter has not yet deserialized the message, so we can't easily get to the IMessage that was passed to us. In the second case, the formatter takes care of the deserialization first, and can then pass the IMessage to the DispatchChannelSinks for further processing and investigation. The overview of .NET Remoting layers from MSDN is lacking a lot of detail, but hints at what causes the differences. Once I went back to Ingo Rammer's book, the technical reason for this behavior became obvious.