Registering Nonscalar Types
Go Up to Using Nonscalar Types in Invokable Interfaces
Before an invokable interface can use any types other than the built-in scalar types listed in Using Nonscalar Types in Invokable Interfaces, the application must register the type with the remotable type registry. To access the remotable type registry, you must add the InvokeRegistry unit to your uses clause. This unit declares a global function, RemTypeRegistry, which returns a reference to the remotable type registry.
The remotable type registry has two methods that you can use to register types: RegisterXSInfo and RegisterXSClass. The first (RegisterXSInfo) lets you register a dynamic array or other type definition. The second (RegisterXSClass) is for registering remotable classes that you define to represent other types.
If you are using dynamic arrays or enumerated types, the invocation registry can get the information it needs from the compiler-generated type information. Thus, for example, your interface may use a type such as the following:
type TDateTimeArray = array of TXSDateTime;
typdef DynamicArray<TXSDateTime> TDateTimeArray;
This type is registered automatically when you register the invokable interface. However, if you want to specify the namespace in which the type is defined or the name of the type, you must add code to explicitly register the type using the RegisterXSInfo method of the remotable type registry.
The registration goes in the initialization section of the unit where you declare or use the dynamic array:
RemTypeRegistry.RegisterXSInfo(TypeInfo(TDateTimeArray), MyNameSpace, 'DTarray', 'DTarray');
void RegTypes() { RemTypeRegistry()->RegisterXSInfo(__arraytypeinfo(TDateTimeArray), MyNameSpace, "DTarray", "DTarray"); InvRegistry()->RegisterInterface(__delphirtti(ITimeServices)); }
The first parameter of RegisterXSInfo is the type information for the type you are registering. The second parameter is the namespace URI for the namespace in which the type is defined. If you omit this parameter or supply an empty string, the registry generates a namespace for you. The third parameter is the name of the type as it appears in native code. If you omit this parameter or supply an empty string, the registry uses the type name from the type information you supplied as the first parameter. The final parameter is the name of the type as it appears in WSDL documents. If you omit this parameter or supply an empty string, the registry uses the native type name (the third parameter).
Registering a remotable class is similar, except that you supply a class reference rather than a type information pointer. For example, the following line comes from the XSBuiltIns unit. It registers TXSDateTime, a TRemotable descendant that represents TDateTime values:
RemClassRegistry.RegisterXSClass(TXSDateTime, XMLSchemaNameSpace, 'dateTime', ,True);
void RegTypes() { RemTypeRegistry()->RegisterXSclass(__classid(TXSDateTime), XMLSchemaNameSpace, "dateTime", "", true); InvRegistry()->RegisterInterface(__delphirtti(ITimeServices)); }
The first parameter is class reference for the remotable class that represents the type. The second is a uniform resource identifier (URI) that uniquely identifies the namespace of the new class. If you supply an empty string, the registry generates a URI for you. The third and fourth parameters specify the native and external names of the data type your class represents. If you omit the fourth parameter, the type registry uses the third parameter for both values. If you supply an empty string for both parameters, the registry uses the class name. The fifth parameter indicates whether the value of class instances can be transmitted as a string. You can optionally add a sixth parameter (not shown here) to control how multiple references to the same object instance should be represented in SOAP packets.