Simplified calls to remote services are among the most useful features of the Java Spring framework. In .NET, I use Castle for the application framework wiring and I was looking for something similar — it turns out that remote proxy calls are incredibly simple with Castle as well.
Spring in Java makes it easy to expose a bean (the equivalent of a Castle component) using several RPC mechanisms and wire that into a client bean on another machine using automatically generated remote call stubs. There are no code changes required in either client or server, and the client actually does not know whether it is talking to a local implementation or a remote proxy.
I wanted to do something similar to that today in a .NET project wired by Castle. Microkernel has a RemotingFacility that performs basically the same function. Although it is documented only in the trunk, the last stable release of the Castle Project also contains this facility — it is just not mentioned in the documentation. On the server side, it allows us to publish a component to the .NET remoting registry and open a port where a remote call can be sent. On the client side, it allows us to define remote components and generates dynamic proxies with the interface expected by clients. And it goes even further than what Spring offers, enabling us to easily set up remoting for entire configuration sets, not just for individual components.
I created a simple example to test how this works. I don’t know the limitations of the facility yet, but I will be putting it to real use soon. The example turned out to be incredibly easy, and it seems very promising.
Impact on the code
The only change required to the server code is that the components that are exposed by .NET remoting have to extend MarshalByRefObject (this is a requirement of .NET remoting, not Castle). This does not seem to heavy, although it prevents the service from extending any other class.
There are no changes required to the client code, and the client does not know that anything out of the ordinary happens.
Configuration on the server
Server Castle configuration requires the RemotingFacility to be initialised with isServer=”true” flag. Castle remoting can work in two modes: publishing individual components or proxying the complete Windsor kernel. I like the second mode better, because it requires less configuration in general, which means less maintenance. Instead of specifying URLs for individual components, we just specify the URL for the kernel. The config below does that with the registryUri flag:
<facility id="remoting" isServer="true" type="Castle.Facilities.Remoting.RemotingFacility, Castle.MicroKernel" remotingConfigurationFile="RemotingServer.xml" registryUri="kernel.rem" />
Notice the remotingConfigurationFile flag. That requires us to specify the path to an external configuration file for the .NET remoting channel. This could have been a bit simpler, I imagine that it could be replaced just by a port property directly in the facility config. Here goes the config file which sets up the .NET remoting on the TCP port 2133.
<configuration> <system.runtime.remoting> <application> <channels> <channel ref="tcp" port="2133" /> </channels> </application> </system> </configuration>
After this, individual components just have to specify the additional remoteserver=”component” flag. Here is how I configured the server component:
<component id="businessservice" service="CastleRemoting.API.IBusinessService, CastleRemoting.API" type="CastleRemoting.Server.BusinessServiceImpl, CastleRemoting.Server" remoteserver="component"/>
Putting the “component” value in remoteserver property allows the container to initialise and load the component when it is called via .NET remoting.
Configuration on the client
On the client side, we initialise the remoting facility with isClient=”true” and specify the URL of the remote kernel with remoteKernelUri (this should correspond to the registryUri from the server config).
<facility id="remoting" type="Castle.Facilities.Remoting.RemotingFacility, Castle.MicroKernel" isClient="true" remoteKernelUri="tcp://localhost:2133/kernel.rem" />
After that, we can set up a dynamic proxy for a remote component simply by specifying the API interface as the service, using System.Object as the initial type and adding the remoteclient=”component” flag.
<component id="businessservice" service="CastleRemoting.API.IBusinessService, CastleRemoting.API" type="System.Object, mscorlib" remoteclient="component" />
And that’s basically it. The component proxy can now be used in other components as if it was a local service. Download the full source code for the example from here. For more information and some different options (eg specifying URLs for individual components), see also the Remoting facility page on CastleProject.org trunk docs. Again, even though this feature is not documented in RC3, the code seems to be there.
Image credits: Sanja Gjenero