1

I'm looking into creating a TService Descendant so that when writing a new service I'm not reinventing the wheel so to speak.

I have created an ancestor worker thread that this TService descendant would be responsible for managing (decendant threads implement the code for the service).

This TService descendant will also have a class for writing to a custom Windows event log, and a thread that checks for new versions of the service from a http server, then updates itself when required.

My problem is what is the best way to instantiate the TService descendant from the project source?

Should the descendant be a pure class or have a dfm/datamodule?

Mike Taylor
  • 2,376
  • 2
  • 17
  • 33
  • 2
    Why didn't you "just" start a new service application? That will create a TService descendant for you (in its own datamodule by the way)? It also takes care of instantiating the service for you in the dpr. (Starting a new service app: File | New | Other | Delphi Projects | Service Application) See http://stackoverflow.com/questions/5744373/service-onexecute-fails-spawned-thread-is-not-executed for a bare bones service app. – Marjan Venema May 18 '11 at 18:58
  • Because it creates a new descendant, I need one that I can reuse with common code for many different services. – Mike Taylor May 18 '11 at 19:02
  • So, inherit from the one the IDE creates again. DataModules support Visual Form Inheritance just like Forms do. So, add a new service datamodule to your dpr and inherit from the service already created by the IDE. Use either the project options | forms to control which one is instantiated from the dpr (the first one in the right hand list) or edit the dpr manually. (File | New | Other | Inheritable Items, should list your first Service data module) – Marjan Venema May 18 '11 at 19:05
  • 1
    In other words: use the TService1 created when you create a new service app as your common base and create your descendent services by inheriting from that base using visual form inheritance. – Marjan Venema May 18 '11 at 19:13
  • 4
    @Marjan, why not copy paste this in an answer, looks like a solution to me. – Johan May 18 '11 at 19:47

2 Answers2

2

You can "just" start a new service application. That will create a TService descendant for you (in its own datamodule by the way)? It also takes care of instantiating the service for you in the dpr. (Starting a new service app: File | New | Other | Delphi Projects | Service Application). Plus it will make sure that the proper units are included as a service application needs the "Application" global var to refer to a TServiceApplication instance and not an instance of what is instantiated for a normal VCL Forms application.

See Service OnExecute fails, spawned thread is not executed for a bare bones service app implementation.

DataModules support Visual Form Inheritance just like Forms do. So, if you want to create descendants, you can add a new service datamodule to your dpr and inherit from the service already created by the IDE. Then use either the project options | forms to control which one is instantiated from the dpr (the first one in the right hand list) or edit the dpr manually.

In other words: use the TService1 created when you create a new service app as your common base and create your descendent services by inheriting from that base using visual form inheritance. File | New | Other | Inheritable Items, should list your first Service data module.

Community
  • 1
  • 1
Marjan Venema
  • 19,136
  • 6
  • 65
  • 79
0

I wouldn't mess with the TService descendant that is created by the IDE too much.

For reusability you can create your own base class "TMyServiceConsumer". You would pass a TService object to it and then you can reuse this class across projects.

It is a classic example of "inheritance vs. composition":

inheritance vs. composition for testability

For the visual vs. non-visual part of your question: It depends.

It is very useful to make the consumer a TDataModule descendant if you often use components and want to have the advantages of RAD.

This is a similar approach to the "TMainWorkThread" in the post Marjan alreasy pointed to in another answer:

Service OnExecute fails, spawned thread is not executed

Community
  • 1
  • 1
Jens Mühlenhoff
  • 14,565
  • 6
  • 56
  • 113