|
||||||||||||||
|
Associating with a ServiceHost
Regardless of the hosting environment, all WCF services must be associated with a ServiceHost instance to be accessible at run time. ServiceHost is part of the System.ServiceModel namespace, and is the centerpiece of the hosting story. A ServiceHost instance is initialized with information about the service type, one or more service endpoints, optional base addresses, and behaviors that govern how the service model processes requests to the service.
Initializing the ServiceHost Listing 1 illustrates a simple example of a console host application initializing the ServiceHost programmatically. In fact, this listing is the entire listing for the host application. The application constructs a ServiceHost instance on startup, supplying the service type: HelloIndigo.HelloIndigoService. A single endpoint is created exposing its HelloIndigo.IHelloIndigoService contract over NetTcpBinding. In this example, the endpoint is initialized with a complete URI, removing the need for any base addresses. After calling the Open() method the ServiceHost begins listening for messages. While the Console.ReadLine() statement blocks the console application to keep the process alive, the application processes incoming requests on their own thread taken from the thread pool. After closing the console, the using statement disposes of the ServiceHost instance calling its Close() method. At this point new requests are rejected while currently processing requests complete gracefully. In this example, the console host only exposes one service. To expose multiple services, you can open multiple ServiceHost instances within the same host process. Declarative Configuration You can also initialize the ServiceHost declaratively via application configuration. In the <system.serviceModel> section you can specify one or more services in the <services> section. Here is an example of declarative service configuration:
As with programmatic initialization, you must specify the service type and one or more endpoints. This example illustrates how to configure a single endpoint similar to the code in Listing 1, with the addition of a metadata exchange endpoint.
Base AddressesIf you specify a fully qualified URI for each service endpoint, you do not need a base address to initialize the ServiceHost. At run time, if you provide base addresses to the ServiceHost constructor you can optionally provide a relative URI to the endpoint address as shown here:
Declaratively, the application provides base addresses in the <host> section for the service configuration:
The ServiceHost builds endpoint addresses by appending the relative address of each endpoint to the base address matching the endpoint's binding protocol. For example, the NetTcpBinding endpoint shown in the preceding code uses the net.tcp base address while the MexHttpBinding metadata exchange ("mex") endpoint uses the http base address. If you omit the address from the <endpoint> configuration, the ServiceHost assumes the base address to be the endpoint address.Service Description
ServiceDescription is part of the System.ServiceModel.Description namespace. It is a run-time abstraction that ultimately generates the Web service Description Language (WSDL) document for the service, and supports interactive metadata exchange (WS-MetadataExchange) with clients. By default, the ServiceHost uses reflection to generate the description-inspecting the service, its contracts, and relevant service behaviors. Figure 1 illustrates how clients can use SvcUtil (svcutil.exe) or the WS-MetadataExchange protocol to initialize a channel at the client and consume a service. Under most circumstances you will not interact directly with the ServiceDescription. However, for advanced scenarios you can control how the ServiceHost generates this ServiceDescription by subclassing ServiceHost and overriding the CreateDescription() method. ServiceHost Events The ServiceHost notifies you of state changes in the channel stack through CommunicationObject events. ServiceHost inherits ServiceHostBase, which inherits CommunicationObject. CommunicationObject is a common base type for many objects participating in the communication channel-providing a common state machine. The events it exposes include Opening, Opened, Closing, Closed, and Faulted. Closing and Faulted are particularly useful for writing event logs or notifying administrators when the communication channel for your service is closing or has encountered a problem. Just add these event handlers to the ServiceHost instance before you open the communication channel, as shown here:
The ServiceHost also has a State property based on the CommunicationState enumeration. You can use this property to detect the following states: Created, Opening, Opened, Closing, Closed, or Faulted.
|
||||||||||||||
|