.NET Remoting

Posts   
 
    
Mac
User
Posts: 17
Joined: 25-Jun-2004
# Posted on: 01-Jul-2004 08:31:42   

Moving thread here.... simple_smile

So, about remoting. Is it efficient way to use it over Internet? I need to create distributed application, that will work between, for example, Ukraine and Canada. I thought about using Adapter pattern, then make an envelope for remoting, using tcp protocol and binary formatting. Do you think this is correct way?

Devildog74
User
Posts: 719
Joined: 04-Feb-2004
# Posted on: 01-Jul-2004 12:01:56   

That is how I would do it.

Mac
User
Posts: 17
Joined: 25-Jun-2004
# Posted on: 01-Jul-2004 12:05:22   

Devildog74 wrote:

That is how I would do it.

And what do you think about perfomance? Will it be better then web services for example?

Ok. I just talked to chief, and this is my next project simple_smile . If it'll work good, i'll think about writing templates for the adapter envelope for the remoting...Seems very interesting to me.

takb
User
Posts: 150
Joined: 12-Mar-2004
# Posted on: 01-Jul-2004 13:02:24   

For info on Remoting, check out:

http://www.thinktecture.com/Resources/RemotingFAQ/default.html

The article on "Use-cases and Best Practices" is a good read.

Regarding performance, read the following article from that site which compares performance between .NET remoting and ASP.NET web services:

http://www.thinktecture.com/Resources/Articles/REMOTINGVS.ASP.NETWEBSERV.html

Devildog74
User
Posts: 719
Joined: 04-Feb-2004
# Posted on: 02-Jul-2004 11:54:17   

Performance will be dictated by many things. Like what is hosting the remote interface, IIS or just TCP/IP? Overall, remoting vs. web services will be much faster. Performance will also be driven by how and what you need to mashal across boundaries.

Here is a good article that compares remoting vs. web services.

http://www.sys-con.com/story/?storyid=44865&DE=1#RES

Mac
User
Posts: 17
Joined: 25-Jun-2004
# Posted on: 02-Jul-2004 13:34:10   

Ok. Here's the deal. I wrote some code for the remoting, and got problems.

I've got server object that implements IDataAccessAdapter.

If you want some client object to be changed by server object (for example you want to fetch entity, da.FetchEntity(MyEntity) da is server object, MyEntity is client object) client object must derive from MarshalByRefObject. I changed runtime libraries (by the way, Frans, what about licensing? Can I distribute changed runtime libraries?), and made EntityBase2 class derive from MarshalByRefObject, but EntityCollectionBase already derives from CollectionBase class, and C# doesn't support multiple inheritance.

Entity fetching works fine, what to do about collections? Any suggestions?

Devildog74
User
Posts: 719
Joined: 04-Feb-2004
# Posted on: 04-Jul-2004 19:59:19   

Are you familiar with the concept of a a facade? A facade is basically a generic wrapper around a set of methods. First start by organizion your database objects into logical namespaces. Take northwind. That database has employees, regions, customers, orders, order details, suppliers, products, etc. You might group your entitties like this:

EmployeeServices: Employees, Regions, EmployeeCustomers EmployeeOrders

OrderServices: Customer Orders OrderDetail

So on an so forth.

Here is how I define my N-tiered apps.

  • Create the v1.0 Database
  • Run your code gen using the adapter
  • Now go back to your logical design and figure out the types of operations that you might want to invoke for different parts of your applications, i.e. getting a list of employees, getting an employee, creating an order, creating order details, etc etc etc.
  • Now that you have your grouping, create a class for each of your Services namespaces, i.e. EmployeeServices, OrderServices, CustomerServices, SupplierServices, etc.
  • Make all of these classes derive from marshalByRefObject.
  • Define interfaces for the method calls that you want to expose in your remote facade
  • Be sure to put your interface definitions in a seperate assembly
  • Implement the interfaces in your services layers. Make all of the methods in these objects static, you could also make the entire class static, i beleive.
  • Make your methods return objects from the DatabaseGeneric Library, or things from the ORM Library like EntityBase2, etc
  • Create a remote component host
  • Create your client app. If will need to reference, the ORM Support Library, the assembly that has the interface definitions, and the database generic assembly
  • Use the interface library as the hook to create your remote proxy to the services objects being hosted by the remote component host
  • Make calls into the remote object using the interface methods. The remoting framework will handle the marshaling. Most, if not all, ORM objects in the database generic will be serializable, so they should marshal just fine.

I also suggest that you read Ingo Rammers book on Advanced Remoting. Because the next thing your going to want to do is build a compression sink and an encryption sink.

That should keep your busy for atleast a day or so. Have fun.

Also, exposing the data access adaper over remoting is not the thing to do. Hide that in the facade. Only let the facade objects talk to the data access adaper.

Mac
User
Posts: 17
Joined: 25-Jun-2004
# Posted on: 05-Jul-2004 14:03:28   

Devildog74 wrote:

Also, exposing the data access adaper over remoting is not the thing to do. Hide that in the facade. Only let the facade objects talk to the data access adaper.

Thanks. I've tried to create a standart wrapper over DataAccessAdapter just to practice in remoting. And i've got some problems, like if you are passing some object as parameter, it must derive from MarshalByRefObject. So, will I use facade pattern or not, I will meet the same problems, i think.

I still don't know how to pass EntityCollection as parameter - i tried to make following: I took source of CollectionBase, rewrote it to derive from MarshalByRefObject. Made EntityCollectionBase derive from my CollectionBase class.In the CollectionBase class the ISerializable interface is implemented, but when i try to pass it to the adapter, i still got an error "Serialization will not desetrialize delegates to non-public methods." So, I'm stuck... I've searched across the net, and found that this exception will occur if ISerializable is not implemented. But it is implemented! I just dont' know what to do now...

wayne avatar
wayne
User
Posts: 611
Joined: 07-Apr-2004
# Posted on: 05-Jul-2004 14:31:18   

Hi

I havn't worked much with ISerializable Interface but i have worked with the '<Serializable()>' attribute.

I took source of CollectionBase, rewrote it to derive from MarshalByRefObject. Made EntityCollectionBase derive from my CollectionBase class.In the CollectionBase class the ISerializable interface is implemented

Don't know if they would behave the same - but if you implement <Serializable()> in your base and inherit from it - it does not mean that your derived child class can be serialized.

So i would assume that ISerializable works in a simular way - therfor ISerializable must be implemented for every object that you want to serialize. It is possible that i am totally wrong...But how would ISerializable know what to serialize if you don't tell it? That is why assume that you are going to have to implement it for every Collection.

Mac
User
Posts: 17
Joined: 25-Jun-2004
# Posted on: 05-Jul-2004 14:44:42   

wayne wrote:

Hi Don't know if they would behave the same - but if you implement <Serializable()> in your base and inherit from it - it does not mean that your derived child class can be serialized.

So i would assume that ISerializable works in a simular way - therfor ISerializable must be implemented for every object that you want to serialize. It is possible that i am totally wrong...But how would ISerializable know what to serialize if you don't tell it? That is why assume that you are going to have to implement it for every Collection.

No, classes that derive from EntityCollectionBase are serializable. I'm sure simple_smile

wayne avatar
wayne
User
Posts: 611
Joined: 07-Apr-2004
# Posted on: 05-Jul-2004 14:56:58   

OK - Then i am totally wrong.simple_smile

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 05-Jul-2004 14:59:26   

Mac wrote:

Devildog74 wrote:

Also, exposing the data access adaper over remoting is not the thing to do. Hide that in the facade. Only let the facade objects talk to the data access adaper.

Thanks. I've tried to create a standart wrapper over DataAccessAdapter just to practice in remoting. And i've got some problems, like if you are passing some object as parameter, it must derive from MarshalByRefObject. So, will I use facade pattern or not, I will meet the same problems, i think.

It's not wise to expose the adapter over the remoting channel because it contains an open db connection which is not serializable. So the adapter itself isn't marked serializable as well. You therefore should create a remoting service which calls the adapter object, accepts entity objects and returns entity objects.

I still don't know how to pass EntityCollection as parameter - i tried to make following: I took source of CollectionBase, rewrote it to derive from MarshalByRefObject. Made EntityCollectionBase derive from my CollectionBase class.In the CollectionBase class the ISerializable interface is implemented, but when i try to pass it to the adapter, i still got an error "Serialization will not desetrialize delegates to non-public methods." So, I'm stuck... I've searched across the net, and found that this exception will occur if ISerializable is not implemented. But it is implemented! I just dont' know what to do now...

You don't need to do this. Entity objects and entity collection objects are not derived from MarshalByRefObject for a reason: when you change a property with such an object you'd get a remoted call, which is very inefficient. Therefore entity objects and entitycollections are serializable and are passed by value: you return an entitycollection from a remoted method, the collection gets serialized into soap or binary depending on your formatter of choice, and at the client side again deserialized into an object. You change values and pass back the object to a remoted method on the server.

All objects which should be serializable are also serializable, so you can pass an entity collection object as a parameter to a remoted method without problems as well as returning one from a remoted method.

Do NOT go the MarshalByRefObject route, it's not used for objects with data, but for objects which deliver a service, i.e. expose methods.

Frans Bouma | Lead developer LLBLGen Pro
Mac
User
Posts: 17
Joined: 25-Jun-2004
# Posted on: 05-Jul-2004 15:19:22   

Ok. Thanks. Now I've got it simple_smile .

Devildog74
User
Posts: 719
Joined: 04-Feb-2004
# Posted on: 05-Jul-2004 19:23:56   

Yeah, what otis said. Thats what I was trying to say.

Only marshal the type that exposes how to get the data. Get the data using the type that has been marshaled to the client.

sami
User
Posts: 93
Joined: 28-Oct-2005
# Posted on: 01-Nov-2005 16:24:44   

What about deriving data adapter from marshalbyref? You could then use that directly from client. Is this totally silly idea or possible?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 01-Nov-2005 16:52:26   

sami wrote:

What about deriving data adapter from marshalbyref? You could then use that directly from client. Is this totally silly idea or possible?

In theory it couldbe possible, though it IMHO also would result in chatty applications, because instead of writing a proper service interface which exposes methods you call to preform an action, you're calling the lower level dataaccessadapter object's methods directly, IMHO this can lead to much more activity, the object isn't usable by multiple clients and the service itself isn't properly designed.

Frans Bouma | Lead developer LLBLGen Pro
sami
User
Posts: 93
Joined: 28-Oct-2005
# Posted on: 01-Nov-2005 19:18:35   

Yes, it could lead to chatty interface, but so could a service implementation, if you don't do it properly. Anyway, I agree with you - with a proper service implementation you can be sure that data adapter is not misused. Although, in smaller projects it might be nice to have an option to use data adapter directly.