Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

WCF the Manual Way…the Right Way : Page 2

Don't be lured by Visual Studio's promise of simple templates for creating WCF services; here's why you should plan to create your services manually.


advertisement
Developing a Service and Consumer with Templates
This section shows how to develop a quick service and consumer using all the automated templates and tools that Visual Studio provides. But before getting started, this article assumes a little knowledge of WCF and thus uses several terms that are specific to the world of WCF, which I'll define here:

  • Service Contract: An interface housing the operation definitions of a service.
  • Operation Contract: A method definition within the service contract which will be implemented by the service.
  • Service: A class implementing one or more service contracts, providing the implementation defined in the contracts.
  • Host: An application platform that serves as a listener for service requests.
  • Proxy: A class on the consume side that's responsible for opening a channel between the consumer and the service and initiating calls to the service operations.
  • Endpoint: Defines where, how, and what a service will provide. This is used on both the service host side and the client side and can be defined in either code or declaratively.
  • ABCs of WCF: The three elements that make up a service endpoint definition: address, binding, and contract
  • Address: A URI location for a service.
  • Binding: The transport protocol to be used in communicating with a service.
  • Contract: The service contract exposed by an endpoint.
Creating a New Service Project
Visual Studio has three WCF-related project templates. Two are web-related; both are called "WCF Service" and do pretty much the same thing. There are two of them because one is available by selecting "Add New Project" and the other by selecting "Add New Web Site". Both these project templates create five things for you:

  • An IIS-based service host
  • References to System.ServiceModel and System.Runtime.Serialization
  • An interface-based service contract
  • A service class
  • Configuration entries in the web.config file
The third project template, called the "WCF Service Library", creates everything above except the service host. The project template adds configuration information in an app.config file. I find this a bit misleading because configuration files are used only in the client application and not in a library project. I understand that the addition of this configuration file is educational—it helps you see what the service parameters will look like—but of course you'd eventually need to copy that information to the client project's configuration file.

I'm going to create a new "WCF Service" project. You'll find the template in the web tree node of the project template dialog. Creating this project provides you with a new web application project that will serve as the service's host. It also creates a code file called IService1 and a service file called Service1.svc. This latter file is analogous to an old web service's ASMX file, and includes a code-behind class file. Since I created a web application project with this project template, the code-behind class for this SVC file is directly under it. If I had selected "Add New Web Site" instead, and chosen the "WCF Service" project template, the SVC file's code-behind class as well as the IService1 code file would have been placed in the App_Code folder.

You might expect that the IService1 code file would contain the IService1 interface that serves as the service contract, but if you open it up you will see that it contains both the IService1 service contract and a class called CompositeType, which serves as a sample data contract. Here are the contents of the IService1 code file:

[ServiceContract] public interface IService1 { [OperationContract] string GetData(int value); [OperationContract] CompositeType GetDataUsingDataContract( CompositeType composite); // TODO: Add your service operations here } [DataContract] public class CompositeType { bool boolValue = true; string stringValue = "Hello "; [DataMember] public bool BoolValue { get { return boolValue; } set { boolValue = value; } } [DataMember] public string StringValue { get { return stringValue; } set { stringValue = value; } } }

The Service1.svc file's code-behind class implements the IService1 interface and provides operation implementations for both defined operations; one that uses the data contract class and one that does not. Look at the code for the actual service:

public class Service1 : IService1 { public string GetData(int value) { return string.Format("You entered: {0}", value); } public CompositeType GetDataUsingDataContract( CompositeType composite) { if (composite.BoolValue) { composite.StringValue += "Suffix"; } return composite; } }

While I understand that the code samples that the built-in templates provides are merely starting points for making your own services and service elements, I feel strongly that Microsoft could have achieved the same results using other (non-existent) templates, such as a "Service Contract" template or a "Data Contract" template.

The Service1.svc file serves as the entry point for this service and looks like this:



<%@ ServiceHost Language="C#" Debug="true" Service="WcfService1.Service1" CodeBehind="Service1.svc.cs" %>

In many ways this resembles an old ASMX file, and like an old ASMX file, the only attribute needed here is the Service attribute, which points to the service class that will be executed when this service entry point is reached.

All the code I've just shown you resides in my new web application project. The web application itself serves as the host for my service and requires a certain amount of configuration. Here's the configuration that Visual Studio added automatically when I created this project:

<system.serviceModel> <services> <service name="WcfService1.Service1" behaviorConfiguration= "WcfService1.Service1Behavior"> <endpoint address="" binding="wsHttpBinding" contract="WcfService1.IService1"> <identity> <dns value="localhost"/> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> <behaviors> <serviceBehaviors> <behavior name= "WcfService1.Service1Behavior"> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>

I won't over-criticize this configuration because it's not really overkill. Although the minimum configuration required to host the service is considerably less, the extra information can be pretty useful. When I mention a service's minimum configuration, I'm referring to the service's endpoint(s). The additional information in the preceding configuration supports the exposure of more detailed error information in fault cases and the exposure of metadata for use when clients use the "Add Service Reference." Using this feature is one of the habits I want to get you out of in this article, so I prefer not to have this included in my configuration.



Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap