Remoting Types in the client (newbie question)

J

Jayme Pechan

I created a C# service and registered its types for .NET remoting. Now I
need to create an instance of the object from a client application.
Previously I had implemented the service in ATL so I just added the
reference and it created an Interop with all the function signatures and
such. As far as I can tell the .NET remoting mechanism isn't that easy.
The following code is the best I could figure out. My problem is that the
Class1 class is defined in the service. How do I get the definitions in the
client?

Class1 myObj =
(Class1)Activator.GetObject(typeof(Class1),"tcp://localhost:16000/Class1");
myObj.Test("Hello World");

I saw an example in the docs but they used a DLL. I can't really do that
because I need the class to be able to access other classes in my service at
runtime. Any ideas?

Thanks.
 
J

Jayme Pechan

If I copy the class definition to the client cs file, the thing compiles but
instead I get a runtime error when trying to call the function.
 
J

Jeff Louie

Jayme... I don't completely understand what you are doing, but be aware
that the
runtime essentially appends the name of the assembly to the fully
qualified class
name so that Assembly1.MyNamespace.MyClass is different from
Assembly2.MyNamespace.MyClass. One solution is to define the common
interfaces into a dll and have both client and server reference the
common dll.

Regards,
Jeff
 
J

Jayme Pechan

I'm trying to allow my web application to call functions in my service for
admin purposes. I think i figured out the server side but the client side
is still confusing. I think all I'm missing is the class definition in my
client application. I am able to connect to the server but it returns an
object that needs to be cast to the class so I can call methods on it. Does
that help clarify it?

In my COM days, this was done by simply exposing an object in my ATL
service. Then when I added a reference in my web application to that
object, it created an interop with all the object methods, properties, and
events so it was real easy to make calls into it. I am working on replacing
the ATL Service with this C# service and as far as I can tell, I need to
change my IPC mechanism to sockets or .NET remoting. I thought .NET
remoting would be easier than sockets in this case.

Jayme
 
J

Jayme Pechan

Ok, I got a little further. I used

csc /noconfig /t:library Class1.cs

Then I added a reference to the web application. This successfully called
the function on the server except that I have to put #if around all the guts
of the code so that it compiles out of the dll.
namespace WindowsService1
{
public class Class1 : MarshalByRefObject
{
public void Test(string s)
{
#if SERVICE
System.Diagnostics.EventLog.WriteEntry("WinSvc",s);
#endif
}
}
}

I then define SERVICE in my service build and all is well. Most of the
namespaces aren't available in the dll so it won't build sucessfully with
the code in there. While this works, it seems quite ugly. Is there a
correct way to do this or is my hack job the right way? It seems like COM
Interop was so much easier so I must not be doing this the right way.

Jayme
 
J

Jeff Louie

Jayme... I have no experience with .NET remoting. The following is
therefor total conjecture.

If I understand you correctly, you are now able to access Class1 from
both the service and client since Class1 is now defined in a separate
library. You are now face with the problem that there must be two
versions of the class, one with access to a service only library.
Perhaps you can use inheritance here to get you out of trouble. You
could define a IRemoteOnly interface and compile this into a separate
library or you could have ClassService derive from ClassClient.

As for IPC, that is not supported on .NET 1.1, but there is an
IpcChannel in .NET 2.0.

http://msdn2.microsoft.com/en-us/library/xcs3s8f3.aspx

Regards,
Jeff
 
J

Jeff Louie

Jayme.. Did you get this to work? I went ahead and built a remoting
service and client. The client class looks like it is just a proxy. The
implementation does not matter, so using an interface seems like the way
to go.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide
/html/cpconBasicRemotingTaskList.asp

If you are implementing another type of service (for example, using a
TcpChannel object) your client can obtain the information in two ways:

Downloading an assembly that contains the metadata.
Downloading the source code for an interface.
Note Using source code will work in two cases. When using server
activation, you can use the source code of an implementation, an
abstract class, or an interface only if you compile this code into an
assembly that is of the same name as the actual implementation on the
server, including any versioning information. (Type identity is based on
both type name and assembly name information.) When using client
activation, you must build a class that is outwardly identical with the
actual server implementation. Specifically, the client class must be in
an assembly of the same name, have the same class declaration, and have
members with the same signatures as those on the server. The
implementation of the stand-in client class does not matter; if the
metadata matches, the remote server will be invoked.

Regards,
Jeff
 
J

Jayme Pechan

I did get it working by using the conditional compilation stuff. I thought
about interfaces but because I'm not able to instantiate interfaces, only
classes, it doesn't really help. I'm surprised there isn't a better way to
do this but it does work.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top