Abstract: This is a 4th article from a list, it shows how to transfer multiple TSOAPDataModule into one and use multiple TDataModules instead.
Originally published Borland Developer Network.

Copyright 2003 by Serge Dosyukov

4th article from “Distributed Information Systems. From A to Z” series.
If you would like to find other articles, there is a list that will help you:

Introduction

In the last article, we’ve created a Standalone Web Service with more than one TSOAPDataModule. It allows us to split our logic between different Data forms to make them smaller. This means our application will spend less time and resources creating and using them when processing requests from the client applications.

As you were able to see it is possible and very useful especially when your application has just a few Data forms and business logic is split between them.

But in some situations, it is not like this. For example, you could have a business object where logic is split by groups of providers which belong to multiple TSOAPDatamodules. Logically it is still one object, but when you look at your WSDL publication you will see many IAppServerSOAP instances… This could be not what you expected.

To be or not to be

So if you really looking for the answer, there it is.

You could move your providers from TSOAPDataModules into TDataModule. You could say what then you will not be able to see your providers from the client side.

But there is a way to publish your providers which are located on TDataModule dynamically via your SOAP interface.

Let’s find out what exactly goes on when a client requests provider data from a server.

If you look into a source code of constructor for TCustomProvider (Provider.pas) you will see that there is a little code that is invoked here, code which registers your provider instance in some global list of available (read “published”) providers.

There is an IF case but we looking for the last couple of lines:

if AOwner.GetInterface(IProviderContainer, ProvContainer) then
  ProvContainer.RegisterProvider(Self);

IProviderContainer is one of a set of interfaces our TSOAPDataModule implements and it is how our provider gets published.

So, as you can see only one thing we have to do is to call the method RegisterProvider:

if AOwner.GetInterface(IProviderContainer, ProvContainer) then
  ProvContainer.RegisterProvider(Self);

From Help-Online:
Adds a provider to the list returned by AS_GetProviderNames.
Call RegisterProvider to make a provider available through the SOAP data modules IAppServer interface. Pass a reference to the provider as the Value parameter. Once a provider is registered, its availability to client applications can be turned on or off using its Exported property.
There is no need to call RegisterProvider for providers that are added at design time or when the SOAP data module is assigned as an Owner in the providers constructor. These are registered automatically.
Before a registered provider is destroyed, it must be unregistered using the UnRegisterProvider method. Providers that have the SOAP data module as an Owner are unregistered automatically from their destructo.

You can implement exactly this when you create an instance of TDataModule in your application. Dont forget, that your SOAPDataModule should exist at this point and should remain static or you will need to re-register your providers each time when TSOAPDataModule instance is created.

Ghost House

Remember all this scary movie where kids stay in a house which appears to be empty and when nightfall all nice old ghosts appear from nowhere?

What I am talking about? Hm, lets build a ghost house.

In some situations, you will not like to have all these TDataModules sit in memory all the time as well as to have TSOAPDataModule instance, or even reregister your providers each time when an instance of TSOAPDataModule is created.

In this situation, we could use our ghost house: storage with the information where our providers are defined (where our Provider class is implemented and what is the name of the Provider). Still, no actual instance exists until it is required.

If we come back from our TV world to computer one, our ghost house became be Factory object, an object which will register and keep information about Providers and allow perform all necessary logic by request. There is still some coding required to make information available offline when TDataModule isn’t created yet, but I think, as it is in many cases, we could accept it.

In Part II we’ve created a sample project to illustrate how to build Standalone Web Service. Im going to use it as a prototype and modify it to implement our Provider Factory object.

Results of this modification are available here.

Factory Object allows:

  • Create and destroy an instance of the factory
  • Provide a method to register TDataModule and Providers
  • Find Provider by name or index (this is part of the request logic that TSOAPDataModule will use when trying to find provider)
  • Create and return an instance of TDataModule and Provider class
  • Populate a list of all providers registered

Note. In a sample project both TDataModules publish the same data but via different providers.