WCF : dynamically switch between local and remote WCF objects

Posts   
 
    
DvK
User
Posts: 318
Joined: 22-Mar-2006
# Posted on: 20-Sep-2007 14:02:34   

Hi,

A question about WCF / remoting. Is there a way (technical possibility) to dynamically switch between using local objects (classes) and remote objects hosted by WCF ? This idea behind this is that a client can choose to execute long-running processes either local or on a faster remote machine.

I've seen that this is basically not a problem for plain method execution, but I also experienced that using constructors and setting properties on objects become "unavailable" in the WCF/Remoting model.

So my question is, how can you make the FULL programming model of a .NET class available in a WCF/Remoting model so you can really switch from local to remote and not changing any local code (like setting/getting properties) ?

Thanks for replying... grtz, Danny

G.I.
User
Posts: 172
Joined: 09-Jun-2005
# Posted on: 21-Sep-2007 10:30:46   

A good way to implement this I think is by using a service locator that locates and instantiates a service implementation based on an interface.

and use the System.Activator class, for example:

public Object CreateObject() { ObjectHandle objHandle = Activator.CreateInstance(this.AssemblyName, this.ClassName); Object service = null; service = objHandle.Unwrap();

return service; }

DvK
User
Posts: 318
Joined: 22-Mar-2006
# Posted on: 21-Sep-2007 11:32:59   

OK, I'm not a specialist on remoting objects. How would you solve such a design issue ?

Situation is as follows, just to make it more clear. Our application uses complex calculations and some clients would like to execute those calculations on very fast machines in order to gain speed. So there must be a possibilty in the application to choose between local or remote execution.

To control those calculations, we designed a pretty complex class which needs to be controlled in detail by setting all kind of properties first and execute a few methods. After that, some of those properties contain resultsets/values which are being reused on reports and in the UI.

For example, see following code :


dim rentalObj as IRentalCalculation '-> interface
dim dtCalcResult1 as dataTable
dim outputValue as integer

If useRemoteServer then '-> useRemoteServer is boolean parameter, set somewhere
     rentalObj = new remoteServer.RentalCalculation '-> initialize remote object
Else
     rentalObj = new RentalCalculation '-> initialize local object
End If

'set some properties
rentalObj.propA = 1
rentalObj.propB = 2
rentalObj.propC = ds.tables(0) '-> ds is passed on as a parameter

rentalObj.CalcDayRental '-> execute calculation

'get some property values which have been set by the CalcDayRental method
dtCalcResult1 = rentalObj.propResult1
outputValue  = rentalObj.propOutputValue


So this is simply what I want to achieve, a seamless use of local of remote objects without changing to much of the existing code.

Kind regards and thanks in advance for any reply !! Danny

G.I.
User
Posts: 172
Joined: 09-Jun-2005
# Posted on: 21-Sep-2007 12:26:56   

Looking at the example, aren't you providing exactly what need, or am I missing the point?

I mean, you create some kind of a wrapper class. This class the contains the possibiltity to use the remote object or the local object

If you take the previous CreateObject method and use that for the local assembly.

You can write somewhere (for example config file) which interface, class and assembly you need to use. Than you use the assembly name and the class name in the previous example.

For example RentalObjectWrapper

in you code you instantiate this as RentalObjectWrapper = new RentalObjectWrapper();

then you can use this wrapper. The real object it uses is defined in the wrapper

In the constructor, set the correct mappings, as in interface, assembly, etc. you need to use

In that wrapper you can do:

private IRentalObject _rentalObject;

if (this.IsRemote) _rentalObject = new SomeRemoteRentalObject(); else _rentalObject = (IRentalObject)this.Locator.CreateObject(); //Previous function

I am now getting little confused what you ask for ... for I think this is basically what you already to in your own example.

DvK
User
Posts: 318
Joined: 22-Mar-2006
# Posted on: 21-Sep-2007 13:45:23   

Ok, thanks for replying ! I attached a complete solution containing the following projects :

  • BusinessLogic -> contains a very simple class + interface (BusinessLogic)
  • ConsoleHost -> host for publishing BusinessLogic object
  • ConsoleClient -> consumes local object + remote object.

When you run the ConsoleClient, the local object is executed just fine, the remote object encounters an error ->

{"Unable to cast object of type 'ConsoleClient.RemoteLogic.LogicClient' to type 'BusinessLogic.ILogic'."}

I hope this VS solution offers more insight information about what I'm trying to accomplish here. Hope you can help me out !

Kind regards, Danny

G.I.
User
Posts: 172
Joined: 09-Jun-2005
# Posted on: 21-Sep-2007 14:08:58   

Can someone help, it's still on pending approval ...

jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 21-Sep-2007 18:44:03   

The Service Oriented approach here is to set up a service facade that takes in a message with the necessary "properties" set, and allows you to call the methods or operations you need to get your information calculated. This isn't an object, but a facade that can construct objects for you.

You can then connect remotely to this service via XML, net.tcp or whatever. The facade is built against an Interface. This interface can also be implemented locally (even with the same facade) and can be called using named pipes, which is extremely fast. This redirection can be made at any time depending on whatever runtime requirements you have.

Let me know if you need more info...

Jeff...

DvK
User
Posts: 318
Joined: 22-Mar-2006
# Posted on: 21-Sep-2007 22:11:23   

I understand what you're saying....but I'm trying to grasp what technically CAN and CANNOT be done in a WCF/Remoting scenario without changing any (or little) existing code in my application where at the moment no Remoting is involved in the technical layout.

That's why I attached a sample VS solution of what I'm trying to accomplish, but it's still "pending" approval...so I've put it on a http-link as well -> http://www.today-it.nl/support/ConsoleHost.zip

Thanks for your input !

mhnyborg
User
Posts: 14
Joined: 26-Apr-2006
# Posted on: 23-Sep-2007 22:08:03   

Take a look at CSLA and the code for the dataportal at www.lhotka.net. CSLA can switch between local and remote executing in the config file.

DvK
User
Posts: 318
Joined: 22-Mar-2006
# Posted on: 24-Sep-2007 09:43:26   

OK, yes I looked at the CSLA framework and he uses a LocalProxy and remote proxy (remoting/wcf) model for application service access of which you can make a choice which model you want to use.

I looks pretty good and solid, but it's not 100% what I was looking for. As far as I could see, most classes are mainly method-only based....and I'm looking for an "option" where you can use class properties as well for in- and output of (return)values, like I tried to explain in my sample solution.

But I'm starting to doubt a little if that's even possible at all.... cry

!! HELP !!

Kind regards, Danny

Rogelio
User
Posts: 221
Joined: 29-Mar-2005
# Posted on: 24-Sep-2007 13:35:36   

Hi,

I have experience only with remoting not with WCF. You can make your object remotable inheriting it from MarshalByRef, adding a couple of lines to the app.config file and add a line at the start of the application to let .net to configure the comunication with the remotehost.

It is a performance killer to change properties to a remote object, because each time to change a property .net makes a call to the remotehost to change the property. It is better to create a manager class (and make this class remotable) with methods only and pass the object (that has the propeties set, this class must be serializable) as parameter, the method called will take care of calling the methods and returning values or object.

DvK
User
Posts: 318
Joined: 22-Mar-2006
# Posted on: 24-Sep-2007 15:24:10   

Ok, that's more like it. How would you incorporate this into the sample ? http://www.today-it.nl/support/ConsoleHost.zip

Regards, Danny

G.I.
User
Posts: 172
Joined: 09-Jun-2005
# Posted on: 25-Sep-2007 08:32:32   

Hi DvK,

your example is .Net Framework 3.0 and I can not test that ... sorry ... besides, Rogelio does make a point. wink

DvK
User
Posts: 318
Joined: 22-Mar-2006
# Posted on: 26-Sep-2007 09:14:14   

Hi Rogelio,

Do you have an example of how to configure this in code ?

grtz, Danny

jtgooding
User
Posts: 126
Joined: 26-Apr-2004
# Posted on: 26-Sep-2007 14:33:01   

Check out this article: http://weblogs.asp.net/cibrax/archive/2006/03/31/441591.aspx

Pablo's blog rocks for info on WCF stuff, I found it a tremendous help implementing stuff due to the lack of solid examples or documentation at times on some topics.

John Gooding

DvK
User
Posts: 318
Joined: 22-Mar-2006
# Posted on: 26-Sep-2007 22:20:47   

OK, thanks ! I'll look into it...

EDIT : Looked at it....but still no example using setting/getting properties on a remote class... frowning All there is to find (mostly) is the good old HelloWorld sample with it's famous IHelloWorld interface to implement, so it's getting quite boring....sunglasses

Maybe this link brings light into the darkness.... http://msdn2.microsoft.com/en-us/library/aa730857(vs.80).aspx