Loose coupling is a recurring theme whenever developing and designing web services for distributed applications. As mentioned in the preceding section, the more artificial dependencies you can remove, the better. One such dependency is hard-coded information about the web service to which a consumer connects. Using Web Services Discovery, client code can be more versatile and agile in its consumption of web services.
Web Services Discovery works on the basis of discovery documents. A discovery document contains vital information about web services contained on a web server. Discovery documents are created on servers with a .disco extension to provide location information about web services hosted by a server. In addition, you can append the ?disco argument to the end of a request for an ASP.NET web service .asmx file to retrieve a discovery document for that service.
Using discovery documents, and other directory facilities such as UDDI to provide dynamic location of web services, you can further remove artificial dependencies from your solution.
The System.Web.Services.Discovery namespace is where the .NET Framework provides tools for reading and writing discovery documents and performing other discovery-related tasks.
To see discovery in action, first create a new web service called ServiceToDiscover and just leave the default "Hello World" service there in the Service.asmx file. Add another web service called SecondService.asmx to the project. When you add the ?disco postfix to the web service URL, for example, http://localhost/ServiceToDiscover/Service.asmx?disco, you get an XML document that looks similar to this:
<?xml version="1.0" encoding="utf-8" ?> <discovery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/disco/"> <contractRef ref="http://localhost/ServiceToDiscover/Service.asmx?wsdl" docRef="http://localhost/ServiceToDiscover/Service.asmx" xmlns="http://schemas.xmlsoap.org/disco/scl/" /> <soap address="http://localhost/ServiceToDiscover/Service.asmx" xmlns:q1="http://tempuri.org/" binding="q1:ServiceSoap" xmlns="http://schemas.xmlsoap.org/disco/soap/" /> <soap address="http://localhost/ServiceToDiscover/Service.asmx" xmlns:q2="http://tempuri.org/" binding="q2:ServiceSoap12" xmlns="http://schemas.xmlsoap.org/disco/soap/" /> </discovery>
Probably the most important part of the discovery document is the information that points to the location of the WSDL contract data. The WSDL contract is used to construct client proxies capable of communicating with the web service.
The code in Listing 33.1 shows how to use the System.Web.Services.Discovery name-space to read and process the information contained in a remote .disco file. This Windows Forms application places each contract reference and SOAP binding in separate ListView controls.
Listing 33.1. Using System.Web.Services.discovery to Process Discovery Documents
Figure 33.2 shows the output of this application after processing a discovery document.
Figure 33.2. Reading information from discovery documents.