tags:

views:

217

answers:

3

Hi there, I am using client side configuration files for a .NET remoting client, and the

RemotingConfiguration.Configure() 

call successfully completes. I have referenced the library where the remote objects are defined in my client.

The problem I am having is that after configuration, when I try to create a remote object using new(), it just creates a local object from the referenced DLL. What am I doing wrong?

Thank you,

A: 
if(!typeof(MarshallByRefObject).IsAssignableFrom(typeof(MyRemoteObject))
  throw new InvalidOperationException(@"If a type doesn't extend MBRO, it is
  marshalled by value.  Make sure MyRemoteObject extends MBRO.");
Will
Hi Will,The remote object I am calling extends MarshalByRefObject. However, when I doRemotingConfiguration.Configure("file.config");MyRemoteObject x = new MyRemoteObject();All I get is a local object that is constructed on the local machine.Thank you again,
azarias
@aza tobsen's got ya on this one.
Will
+2  A: 

On the client site you need to call

IYourRemoteObjectInterface remoteObj = 
(IYourRemoteObjectInterface)Activator.GetObject(typeof(IYourRemoteObjectInterface),
 "tcp://remotehost:1002/Test");

in order to retrieve a remote proxy object from a server which is configured as this:

<configuration>
 <system.runtime.remoting>
  <application name="server">
   <service>
    <activated type="remote.ServiceClass, serviceclassassembly"/>
   </service>
   <channels>
    <channel ref="tcp" port="1002">
     <serverProviders>
      <formatter ref="binary" typeFilterLevel="Full"/>
     </serverProviders>
     <clientProviders>
      <formatter ref="binary"/>
     </clientProviders>
    </channel>
   </channels>
  </application>
 </system.runtime.remoting>
</configuration>

Maybe you should read some tutorials for .net remoting in order to learn the differences between Client and Server Activated objects and between singlecall and singleton instances.

tobsen
the issue is with using the 'normal' style new() creations, not the Activator.GetObject construction. Thank you again.
azarias
(And using a client-side config file to achieve that).
azarias
If you use new yourConcreteClass(); the remoting framework has no chance to intercept this and has no way of providing a remoteproxy object. If you want to keep your client application unaware of the remoting infrastructure, you should either use a factory which encapsulate the creation of remoting objects or you may take a look at spring.net's remoting support (e.g. Spring.Remoting.SaoExporter, http://www.springframework.net/doc-latest/reference/html/remoting.html#remoting-publishsao).
tobsen
Tobsen's comment is incorrect. What azarias is trying to do is not only possible, it's the recommended way to create a .NET remoting object. See my answer for what he is (probably) doing wrong.
mhenry1384
Whoops, mea maxima culpa! Especially I was wrong about "If you use new yourConcreteClass(); the remoting framework has no chance to intercept this and has no way of providing a remoteproxy object". Also the msdn says that both calling activator.getinstance as well as calling new yourconcreteclass() are ok (http://msdn.microsoft.com/en-us/library/w93betdk(v=VS.80).aspx).Again sorry! mhenty1384 and azarias. I hope however that you had a look into spring.net and pushed the Remoting infrastructure to the edge of your architecture ;-)
tobsen
+1  A: 

There is something wrong in your configuration file. Most likely your assembly is wrong. For example if your configuration file looks like this:

<configuration>
  <system.runtime.remoting>
    <application>
      <client>
        <wellknown
          type="Foo.MyService, WRONGASSEMBLY"
          url="tcp://localhost:33000/MyServiceUri" />
      </client>
    </application>
  </system.runtime.remoting>
</configuration>

Everything will compile and run but you will use a local copy of the object instead of the remote copy. The assembly in the config file should be the assembly that your object resides in. So if you put the object in a common assembly and reference that, the common assembly will be the assembly you want.

If you don't feel like creating a common assembly, you can even include the source file that contains your object in both projects, but, and this is the surprising bit, the assembly you put in the configuration file will be your CLIENT assembly (not the server).

In other words, the assembly mentioned in the configuration file tells .NET what object in your code should be redirected to a remote location, it is NOT where the object is located (that's what the "url" is for). "namespace.typename, assembly" fully describes the object so remoting can switch the object new call into making a proxy.

There are some good examples here: http://www.codeproject.com/KB/WCF/net_remoting.aspx

mhenry1384