In many ways, the .NET runtime is a parallel concept to COM: It allows two or more applications or components to interact while they are executing. .NET remoting is a parallel concept to DCOM: It allows two or more applications or components to interact while executing on different computers. The mechanics of creating and using a remoted class are remarkably simple. If you have experience with DCOM or CORBA, don't expect .NET remoting to be similar: There's very little difference between writing a pair of classes that will interact remotely, and writing a pair of classes that will interact on the same machine. The base class libraries include a class called MarshalByRefObject , in the System namespace. A remoted class must inherit from this class. Because a managed class can inherit from only one class, you might have to adjust your design to allow MarshalByRefObject to be the base class for your remoted class. To build this chapter's example, create a .NET project, a class library called Greeting . Add a generic C++ class called Greeter . Remove the generated constructor and destructor from Greeter.h and Greeter.cpp, and then edit the class definition to read like this: namespace Greeting { public __gc class Greeter: public MarshalByRefObject { public: String* Greet(String* name); String* Greet(); Data::DataSet* Records(); }; }
You can offer any methods you want from a remoted class, of course. These examples show how to pass and return strings, and how to return a data set. Remoted objects are typically in business or data layers , which makes these return types typical. Edit Greeter.cpp to include these implementations of the functions: using namespace Greeting; String* Greeter::Greet() { return "Hello!"; } String* Greeter::Greet(String* name) { Text::StringBuilder* ret = new Text::StringBuilder(S"Hello, "); ret = ret->Append(name); ret = ret->Append(S"!"); return ret->ToString(); } Data::DataSet* Greeter::Records() { Data::DataSet* ds = new Data::DataSet(); ds->ReadXml("c:\people.xml"); return ds; } Of course, a method in a data layer that returns a data set would normally fill it from a database. In order to make this example work on a variety of machines, it just reads a file of XML. The connection between XML and data is discussed in Chapter 11, "Writing a Data Layer in Managed C++." Using a file of XML like this is a great way to prototype an application that involves data. In order for this code to compile, add a reference (using the .NET tab of the Add Reference dialog box) to System.Web.dll. In order for it to run, you'll need a file of XML. Add one to the project by right-clicking Greeting in Solution Explorer and choosing Add, Add New Item, and then selecting XML File. Name it people.xml and edit it to read like this: <?xml version="1.0" encoding="utf-8"?> <people> <person> <name>Kate Gregory</name> <website>www.gregcons.com</website> </person> <person> <name>Joe Somebody</name> <website>www.somewhere.org</website> </person> <person> <name>Sue Whoever</name> <website>www.wherever.net</website> </person> </people> Save the file, and then copy it to the c:\ folder. You'll need it there when you test these classes on your development machine, before deploying them to a second machine. Finally, delete Class1 , defined in greeting.h, because you have no need for it. Build the solution to confirm that there are no errors. This is a straightforward class library; the only thing that sets it apart from any other class library is that the Greeter class inherits from MarshalByRefObject . |