Class Factories (Delphi)

Overview

This sample demonstrates how to use a Class Factory to generate three types of server:

  • Single Call: Service object instances are created on demand and destroyed after processing the method call – this is the default behavior.
  • Singleton: All clients access a single service object instance.
  • Pooled: A limited number of service object instances is created, the first free instance is used to serve a call. This factory works exactly the same as Singleton, unless the first server instance is busy.

Note: To test this sample properly, you need to run at least two clients.

Getting Started

  • Compile and launch the server and click Activate.
  • Compile and run at least two copies of the client.
  • For the singleton class factory, set any integer value on any client. The value is stored in the service object instance. Then click Get on any other client. The value that has been set is returned proving that the client works with the same service object instance:

  • Do the same with the Pooled class factory and see that the second client returns the value the first client sets. This means that the server gets the same (first) service instance from the pool.
  • Change the scenario for the pooled class factory: Set the value from the first client and also call the Get method from the first client. Don't click OK on the warning dialog! Doing this we imitate the busy status of the service instance. After that, set the value of the second client and call the Set method from it – the requests are served by the second pooled instance because the first one is busy. The server returns two different values that were set by the first and the second clients accordingly.

Examine the Code

  • See how the three services were defined by editing the service library. Do this by making the server the selected project and by using the menu option: RemObjects | Edit Service Library.

Note: If you don't see this menu option, but see Service Builder instead, you still have the client set as the current project.

  • The implementation of all three server types is held in three _Impl.pas files: SingletonService_Impl, SingleCallService_Impl and PooledService_Impl. The only significant difference of those files is the class factory creation part:
  • The implementation of all three server types is held in three _Impl.pas files: SingletonService_Impl, SingleCallService_Impl and PooledService_Impl. The only significant difference of those files is the class factory creation part:

Singleton class factory:

fClassFactory := TROSingletonClassFactory.Create('SingletonService',
                                                 Create_SingletonService,
                                                 TSingletonService_Invoker);
[ROSingletonClassFactory]

Single Call class factory:

fClassFactory := TROClassFactory.Create('SingleCallService',
                                        Create_SingleCallService,
                                        TSingleCallService_Invoker);
[ROStandardClassFactory]// can be ommited, this classfactory is used by default

Pooled class factory:

fClassFactory := TROPooledClassFactory.Create('PooledService',
                                              Create_PooledService,
                                              TPooledService_Invoker, 
                                              2);  
[ROPooledClassFactoryAttribute(2)]

Notice that the default Single Call class factory is generated by the code generation facility. If you need to use another factory you have to replace the corresponding line manually.

  • Examine the simple code needed to invoke the methods in ClassFactoryClientMain.pas.
var 
  service: ISingleCallService;
begin
  service := CoSingleCallService.Create(ROBINMessage, ROIndyTCPChannel);
  try
    service.SetValue(seSingleton.Value);
  finally
    service := nil;
  end;

Concepts Covered

  • Class Factories
  • Per-Request instantiation - this is the standard class factory; a new service instance will be created for each incoming request, and destroyed afterwards (default)
  • Singleton - a single service instance will be used to serve all calls (with different synchronization options for thread safety)
  • Pooling - a pool of instances will be maintained to server incoming requests