It appears that a client proxy instance for and out-of-process ServicedComponent expects the client to have a compile-time reference to the ServicedComponent assembly, unless ServicedComponent is either of different CLR version or has different bitness (either client or server is x64 while another one is x86). This creates a bizarre problem: if the client has no design-time reference to the ServicedComponent, Activator.CreateInstance(compoentClsID) fails if the component is of the same bitness and CLR version with a cryptic "Cannot load type" RemotingException, while working perfectly fine when ServicedComponent is of different bitness or compiled targeting different .NET Framework version. Google offered no insight, so I started thinking of why matching CLR and bitness would lead to failure. I started suspecting that when client and server have mismatched CLR/bitness attributes, runtime must be doing cross-process marshalling in somewhat different manner than when attributes match. Now what I needed is to ensure that same "deep proxying" is taking place when client and server have matching CLR/bitness. On the hunch I decided to use overloaded Type.GetTypeFromCLSID(clsID, "localhost"), and lo and behold, it worked! Now I have a client that at design time is only aware of ServicedComponent's interface, but does not hold a direct reference to it, and yet it is able to talk to multiple out-of-process ServicedComponent implementing same interface while having different CLR and bitness attributes. At the end of the day it turned out to be possible to instantiate ServicedComponent while knowing neither its CLSID at the design time nor having a hard reference to the assembly implementing ServicedComponent.