官术网_书友最值得收藏!

Hosting services

Now that we've identified the core components of a WCF endpoint, the giant remaining question is: how do I make this service available to consumers? You are able to host your service in a variety of places, including:

  • Self-hosting: You can create a managed .NET application such as a Windows Form or Console application that acts as the host for your service. A self-hosted service can use any of the available WCF bindings but offers the least infrastructure for service hosting. This avenue is typical of demonstration or proof-of-concept scenarios and is not really considered enterprise grade.
  • Windows Service: You could choose to build a Windows Service that hosts your service in a more managed fashion. Also considered a form of self-hosting; it too can support the full range of WCF bindings. This is a bit better than manually building a service host because, through the Windows Services platform, you get more manageability and support for failure recovery, automatic startup, and association with a specific Windows identity.
  • IIS: You can serve up WCF services that have HTTP and HTTP/S endpoints. Here you get the full power of an enterprise web server and the availability, process separation, and host lifecycle management that comes along with it.
  • In-process WCF: The premier WCF hosting environment is IIS 7.0 or above, alongside Windows Process Activation Service (WAS). This is available in Windows Server 2008, Windows Vista, and more recent Windows versions. With IIS 7.0 and above, you can host services that rely not only on HTTP communication, but also on three other WCF protocols (TCP, MSMQ, and Pipes). So you get an integrated IIS experience regardless of the transport protocol. This is a fantastic way to get web server benefits (process recycling, health monitoring, and so on) for non-HTTP based services.

For our examples here, I'll use a self-hosted service. While it is very simple to use IIS 7.0 to host our services, the self-hosted paradigm forces us to create (and learn) the host activation plumbing that IIS nicely hides from you. In our case, the host is a Console Application project in Visual Studio. Let's look at the complete host and then dissect it a bit:

using System.ServiceModel;
using System.ServiceModel.Channels;

class Program
{
    static void Main(string[] args)
    {
      string address = "http://localhost:8081/VServiceBase";
      Binding httpBinding = new BasicHttpBinding();

      ServiceHost vendorHost = new ServiceHost(
         typeof(VendorService), 
         new Uri(address));

      vendorHost.AddServiceEndpoint(
        typeof(IVendorContract), 
        httpBinding, "");

      vendorHost.Open();
      Console.WriteLine("Vendor host opened ...");

      Console.ReadLine();

      vendorHost.Close();
    }
}

So what do we have here? First, I created a string to hold my base address. A base address acts as a root for the service from which a series of endpoints with relative addresses may be based upon.

Next, I created an object for BasicHttpBinding. We could have used any WCF binding here, but given that I chose an HTTP base address, I chose one of the available WCF bindings that supports HTTP.

Now comes the important part. The ServiceHost object essentially instantiates the service, configures the endpoint, applies security, and starts to listen on the requested URI. The constructor I used for ServiceHost first accepts the service implementation class object. The second parameter is an array of base addresses for the service. Note that we could have multiple base addresses, but only one per URI scheme. for instance, I could have both an HTTP base address and a TCP base address for my service and then have endpoints defined that use either of the available base addresses.

On the next line of the Console Application, I call the AddServiceEndpoint operation on my ServiceHost instance. This operation accepts the contract used by the service, the binding of the endpoint, and optionally, the relative address. Note that our endpoint has the full ABCs of WCF applied. Finally, I opened the host which led to the service endpoint being available for consumption.

Now, you may look at this and wonder why you'd want to hardcode this type of connection information into your host. How do you deal with service promotion through multiple environments where the address constantly changes or achieve all this flexible goodness that WCF evangelists always talk about? This is where we gently shift into the concept of storing service configurations in an external XML file. If there is one thing you will learn from your forays into WCF, it's that configuration is key and configuration files get pretty darn big.

If we add an application configuration to the Console Application in Visual Studio, all the address, binding, and endpoint decisions are moved from code to configuration. The self-hosted service we just saw has much simpler code when a configuration file is used, as shown:

class Program
 {
  static void Main(string[] args)
  {
      ServiceHost vendorHost = 
          new ServiceHost(typeof(VendorService));
            
      vendorHost.Open();
      Console.WriteLine("Vendor host opened ...");

      Console.ReadLine();
      vendorHost.Close();
  }
 }

Much shorter, eh? The application configuration (app.config) file associated with this self-hosted service looks like this:

<configuration>
  <system.serviceModel>
    <services>
      <service name="BizTalkSOA.Chapter2.ServiceImplementation.VendorService">
      <endpoint 
        address="" 
        binding="basicHttpBinding" 
         contract="BizTalkSOA.Chapter2.ServiceContract.IVendorContract" />
       <host>
         <baseAddresses>
           <add baseAddress="http://localhost:8081/VServiceBase" />
         </baseAddresses>
        </host>
       </service>
     </services>
    </system.serviceModel>
</configuration>

Note how the values (for example, base address, binding, contract, and service implementation) previously spelled out in code are now all present in a configuration file. As you can imagine, it's quite simple to add new endpoints, change base addresses, and switch binding parameters in an XML configuration file.

Note

As far as I can determine, the only reason you would choose to embed WCF endpoint details in the service host code would be when either (a) the address and channel stack are never expected to change or (b) the address and channel stack are set dynamically based on runtime conditions. Other than this, storing these transport values in an external configuration file provides the greatest level of flexibility and extensibility for WCF host solutions.

Is this all there is to a hosted WCF service? Hardly so. Once the endpoint has been defined, we decide which binding settings to modify. For instance, I could explicitly set up a basicHttpBinding configuration and define service timeout values, message size limits, and a specific security scheme. There are a wide array of service variations that may be designed by manipulating these binding configurations.

While binding configurations play a key role in refining the way the service operates over the wire, WCF behaviors are used to provide custom extensions to the WCF runtime. There are four places where behaviors may be applied in a WCF solution:

  • Contract
  • Operation
  • Endpoint
  • Service

For example, we can apply a serviceMetadata behavior to the service in order to allow clients to investigate the service WSDL. Also, at the service level, we are capable of controlling the number of concurrent calls via the serviceThrottling behavior. Most importantly, it's fairly straightforward to build new behaviors that can be customized and reused by multiple services. For instance, we could build a custom interceptor, which logs all inbound messages to a database. We'll see examples of custom behaviors in future chapters.

主站蜘蛛池模板: 嵊泗县| 通化县| 东光县| 渝中区| 平凉市| 年辖:市辖区| 嘉祥县| 肇庆市| 永城市| 宿迁市| 靖江市| 昌邑市| 海宁市| 郯城县| 梓潼县| 乌拉特中旗| 大埔区| 宾川县| 阿鲁科尔沁旗| 富宁县| 新巴尔虎右旗| 徐水县| 清水河县| 洛宁县| 蓝田县| 锦州市| 仪陇县| 克什克腾旗| 舒城县| 常山县| 漳平市| 呼伦贝尔市| 禹城市| 峨山| 尼勒克县| 大方县| 孟州市| 泾川县| 玉龙| 贞丰县| 辽阳市|