As is common knowledge remoting needs server assemblies on the client for remote communication. In many cases sharing server implementation with the clients is undesirable. Interfaces can be used to acheive this isolation. An assembly which contains only interface definitions can be shared between the client and the server. A class factory pattern can be used if client needs to create instances rather than communicating with a wellknown object.

The server can define its types like this:

public class RemoteFactory : MarshalByRefObject, IRemoteFactory {

   IFoo IRemoteFactory.CreateIFooInstance()
   {
       return new Foo();
   }
}

public class Foo: MarshalByRefObject, IFoo
{
....
}

The client connects to the factory using:

// Connect to the factory
IRemoteFactory factory = (IRemoteFactory)RemotingServices.Connect
     (typeof(IRemoteFactory), "tcp://remoteHost:8080/factory.rem");
// Create IFoo instance remotely
IFoo foo = factory.CreateIFooInstance();

This essentially gives client activated style behaviour without having to share type implementation with clients. Thus, in the pseudo code above IRemoteFactory and IFoo would need to be shared between client and server, whereas RemoteFactory and Foo could be private to the server.

Same technique will work for x-domain cases when its required to keep some appdomains unpolluted by types loaded in other appdomains