The document provided by Matthew Green w/c presents a Serviced Based Architecture in Powerbuilder is the basis for all Kodigo services. Here is a shortlist of the features of this Architecture:
- Services are stateless.
- Services appear as singletons, meaning only one instance of a particular service will ever be created, whether there is 1 or 100 requestors.
- Services are automatically destroyed (if #Pooled = false, more on this later) when there are no more requestors
Usage example:
ServiceManager
services
StringService
svcString
services.LoadService(svcString,
"StringService")
string lsRet
lsRet =
svcString.Format(ls, {"0", "1"})
Now let's walk through the above code
ServiceManager
services
The class ServiceManager acts as the broker for service creation. It is also responsible for tracking usage count and service destruction. In essence, this class represents most of the features of SBA.
StringService
svcString
The sample service StringService is inherited from ServiceBase. All service functions should be stateless, meaning they do only one thing and be done with it. State should be held by the requestor.
services.LoadService(svcString,
"StringService")
This call basically tells ServiceManager to create a service called StringService (w/c is the classname of the service) and place the instance on variable svcString. Let's take a look at the figure below on what the ServiceManager is doing to create the service.

- Requestor calls ServiceManager.LoadService()
- ServiceManager searches instance cache for matching service. If found, increments usage counter and returns service instance to requestor.
- ServiceManager searches shared cache for matching service. If found, adds the service to the instance cache, increments usage counter and returns service instance to requestor. If not found, creates the service in the shared cache, adds service to the instance cache, increments usage counter and returns service instance to requestor.
- Requestor receives service class.
Now you may be asking, what is the point of having an instance cache when the shared cache will do fine? Well, the main reason is how usage counter is decremented and services eventually destroyed. We'll go deeper into that subject later, for now, let's look at the definition of ServieManager in PB in order to uderstand the instance cache design.
First of all, ServiceManager is an autoinstantiated nonvisualobject. This means that PB will create the nvo as soon as it is declared. PB will also destroy the nvo as soon as the variable goes out of scope. Where you declare ServiceManager is critical on how effective SBA will be. For now, it is important to always declare it as a local variable. Later on I will discuss other options for declaring ServiceManager, depending on the service and situation.
When a ServiceManager variable goes out of scope, PB will automatically destroy the object. In ServiceManager's destructor event, it will unload all services found in its instance cache. So when there are two ServiceManagers in memory, and they have loaded the same service
<TODO>