DSS Service Startup
Glossary Item Box
When a DSS service is started there are several steps that occur:
- A new instance of the Service class is created plus a transport and forwarders (so that messages can be sent to the Operations Port);
- The service is bound to the network and given a URI (which might have a GUID appended to make it unique);
- If partners are required, they are started and/or found;
- The Start() method in the service is called.
Note that if a service has declared a partner with "Use Existing" then DSS will wait for a period of time before calling Start() so that the partner service has a chance to start up. This can make it appear that Start() is not being called if you run in the debugger and expect to see a breakpoint hit immediately in Start().
During the startup process information is obtained from the service DLL using reflection. Part of the process is also to mount embedded resources, at least one of which must be referenced with an EmbeddedResource attribute.
The service must call base.Start() or perform equivalent functions itself in order to complete initialization.
The steps that base.Start() performs on behalf of the service are:
Call ActivateDsspOperationHandlers() on all main and alternate ports, trying to hook up handlers (add them to the main interleave) that have the ServiceHandler attribute based on the method signatures and the operations defined in the Operations Port;
Send a DirectoryInsert() for the service;
Issue a LogInfo with the URI of the service (for debugging purposes).
Note that the ServiceHandlerBehavior specifies the type of handler. If the Behavior is omitted, then DSS attempts to add the handler to the main interleave based on the DSSP verb, e.g. an Update operation must use an Exclusive handler.
If you have marked a handler with ServiceHandler but there is no corresponding operation, an error message is displayed but the service continues. There are several operation handlers that are included in the DssServiceBase class, such as Get and HttpGet. These do not need to be in your code unless you want to override the default behavior.
In general, a service should delay calling base.Start() until after it has completed all its internal initialization. This might be a little complicated if you spawn an iterator to perform the initialization. A call to base.Start() is inserted into the Start() method automatically by DssNewService. You might be tempted therefore to place your initialization code after this call, but in most cases you should place it before the call to base.Start().
There is no requirement to call base.Start() and a service can do these steps itself. However, if you omit steps 1 or 2 then your service might not be properly initialized.
By delaying the DirectoryInsert(), a service can remain "invisible" until it is ready. Services that must wait on other services to be ready can subscribe to the directory and listen for notifications that the other services are available.
An alternative is to send a Get request to a service that you must wait for and wait until you receive the response. For this to work properly, the service you are trying to coordinate with must not hook up its handlers until it is ready. Because base.Start() hooks up the handlers, it should therefore be the last step in the initialization code. Messages, such as Get requests, that are sent to the service in the meantime will be queued because the Operations Port is created in the very first step of service creation.
DSS Service Tutorials: Service Tutorials Overview
© 2012 Microsoft Corporation. All Rights Reserved.