Tải bản đầy đủ
Objective 3.1: Create a WCF Service

Objective 3.1: Create a WCF Service

Tải bản đầy đủ

What communication mechanisms does it support? Without answering these questions, it would be impossible to consistently and reliably communicate with a service.
■■

■■

■■

Services are autonomous  The service and any items it contains must be independently deployed, versioned, and managed.
Services share schema and contract, not class  To communicate with a service, a
client needs to know the uniform resource identifier (URI), the protocol the communication will happen with, and what operations are supported. It should not need a copy
of the class or library that provides the operations.
Service compatibility is based on policy Although Web Service Definition Language (WSDL) can provide a tremendous amount of information, it cannot communicate every possible requirement a service might have. MSDN put it most eloquently,
“Policy expressions can be used to separate structural compatibility (what is communicated) from semantic compatibility (how or to whom a message is communicated).”

In its simplest form, a WCF Service is just another compiled class file (or group of files). You
can create a simple class library and add some specific references, use some specific classes
and attributes, and end up with a WCF Service. Or, you can use Visual Studio and built-in
templates to create your services. The former approach isn’t even worth discussing other than
to point out that there’s nothing magical about WCF Services; they’re just like any other item
you’ll work with in Visual Studio.
If you’re taking the test, I have to assume that you are at least familiar with some of the
basic concepts of WCF such as hosting, bindings, and endpoints. If you are not familiar with
these concepts, you should become familiar with an overview of WCF before proceeding.

Creating contracts
Remember from SOA tenet 3 that “Services share schema and contract, not class.” As such,
the critical elements of a service should be represented by a contract so that clients and services can communicate in a much more flexible manner. There are several types of contracts
that can be used inside a WCF Service, including the following:
■■

■■

■■

■■



ServiceContract attribute  What actually makes a given .NET type a WCF Service.
Without a ServiceContract, you don’t have a WCF Service unless other contract elements are defined; it does nothing more than identify something as a service.
OperationContract attribute  Marks a function as an operation that is part of a
given service.
DataContract attribute  Informs the runtime that the contained type will be
serializable.
FaultContract attribute  Provides information on exceptions in a platform-agnostic
manner.

Objective 3.1: Create a WCF service

CHAPTER 3

171

As stated before, WCF Services are simply assemblies at their core. So you can build a WCF
Service and consume it just like any other class in .NET. But doing so won’t provide any benefits that creating it as any other class wouldn't, and it would add unnecessary overhead. In
order to create it in a manner that it can be consumed in a different process in a distributed
manner, or both, it needs to be hosted. Any .NET AppDomain can host a WCF Service, and
like its sibling Workflow Foundation, WCF Services have the capability to be self-hosted.
When you’re ready to create a WCF Service, you have a few choices:
■■

You can use the New Web Site option and then choose WCF Service. Visual Studio
does not just create the core WCF project and add the needed assembly references
for you. It also builds the host application. In so doing, the corresponding bindings are
automatically added, and starting with version 4.0 of the .NET Framework, much of the
configuration is handled by default. If you use this approach, however, the bindings
you can use are limited. Figure 3-1 illustrates the dialog box in which you can create a
new website using the WCF template.

FIGURE 3-1  New Web Site dialog box to create a WCF Service
■■

172

You can create the WCF Service using one of the WCF-specific templates, including
the WCF Service Library, WCF Application, WCF Workflow Service Application, and the
Syndication Service Library template. Figure 3-2 shows the available options for using
one of the default WCF templates.

CHAPTER 3

Designing and implementing WCF Services

Because versioning and hosting are covered among other topics, the sample code is done
using a WCF Service Library project. You start with it and build on it.
If you examine the available options shown in Figure 3-2, the two most common options
are WCF Service Library and WCF Service Application. If you think back to creating a Windows
Form or console application, you usually want to avoid putting all your application logic in the
executable program. Doing so greatly reduces your ability to reuse or distribute your code.
The same principle applies here. You’ll likely need to reuse your service or components of the
service and you’ll frequently need to create more than one service in an application. Creating
a service library helps facilitate reuse and isolation. The distinction, however, is much simpler
than it might sound. If you want to create a host independent service or set of services, use
the WCF Service Library template. If you want to create a service or set of services that includes a host—and that host will be Internet Information Services (IIS) or Windows Activation
Service (WAS)—use the WCF Service Application template.

FIGURE 3-2  Creating a WCF Service using WCF Service templates



Objective 3.1: Create a WCF service

CHAPTER 3

173

At this point, if you want to follow along with building the code, create an empty solution
(this one is named Microsoft.FourEightySeven.ChapterThree). To do this, follow these steps:
1. Open Visual Studio, select File→New Project→Other Project Types→Empty Solution.

Figure 3-3 illustrates the New Project dialog box in Visual Studio 2012.

FIGURE 3-3  Creating an empty solution

2. Click the Solution node of the solution you just created in Step 1 (here, it is named

Microsoft.FourEightySeven.ChapterThree). Go to the Project menu and select Add New
Project→WCF→Service Library (here, it is named Samples.WCF.Services, but you can
name it whatever you like). Figure 3-4 shows the Add New Project dialog box.

174

CHAPTER 3

Designing and implementing WCF Services

FIGURE 3-4  Adding a new WCF Service library

MORE INFO  WINDOWS ACTIVATION SERVICE (WAS): A SERVICE LIBRARY IS JUST A .DLL

You don’t have to use any of the installed templates. As you’ll see shortly, the output is
simply a traditional assembly (.dll). You can just create a standard class library project and
add a few project references, but don’t waste your time and effort using that approach unless you feel like doing it the challenging way.

At this point, you see a project (named Samples.WCF.Services, unless you named it otherwise). When you create the WCF Service Library project, Visual Studio adds several references
for you: a default service class and an interface class. The interface and service class are both
predecorated with the ServiceContract and OperationContract attributes. These classes along
with attribute decorations form the basis of what’s needed for a regular .NET Assembly to
become a WCF Service (or Services). This sets the groundwork for this chapter. Figures 3-5 and
3-6 show images of the Solution Explorer window after the solution and project have been
created. Become familiar with them.



Objective 3.1: Create a WCF service

CHAPTER 3

175

FIGURE 3-5  Solution Explorer view of WCF Service library

So what’s significant about Figure 3-5? It shows what differentiates a WCF Service as opposed to a traditional class library. The main differences you see are these:
■■

■■

An assembly reference is automatically added to the System.ServiceModel and the
System.Runtime.Serialization assemblies.
An Application Configuration file is added to the project. (The contents of this file
are covered in-depth in the “Configure WCF Service settings by using configuration
settings” and “Host and manage services” sections.)

A file representing the service (Service1.cs) was added, along with a matching file containing the interface definition for the service (IService.cs). By default, the name of the interface
and the corresponding file name match the name of the service, differentiated only by the
letter “I” at the beginning (which is the Microsoft-recommended naming convention for
interface definitions). In practice, you might have one definition for different services because
one service can implement several different interfaces, so the names don’t necessarily match.
Additionally, many developers find it beneficial to separate the service interfaces into their
own assemblies, but the reasons for doing so are not something tested on this exam.
If you right-click the Project node and select the Properties option, you see the project options related to WCF Service libraries (see Figure 3-6) under the Application section.

176

CHAPTER 3

Designing and implementing WCF Services

FIGURE 3-6  Project options related to WCF Service libraries

You’ll see the Assembly Name and Default Namespace settings just as you would on any
other project, but the two items of distinction are these:
■■

■■

The Output Type is specified as a class library (again, this reinforces the statement that
WCF Service libraries are just like any other class library with minor differences).
The Startup Object is not set because there is no specific startup object needed here.
In some cases, you might have one service definition in an assembly, but it’s possible
to have any number of services contained in a library, and none of them is inherently
dependent on any other one.

For the sake of readability, change the name of the Service to TestService and the interface
to ITestService, so the file names reflect those changes. If you change the file name using the
Visual Studio rename feature, it’ll prompt you to change the names of the contents, which in
turn automatically makes the configuration contents match the new names. If you don’t use
the rename feature, you have to do this manually, which tends to be both tedious and errorprone.
Because each service must include a contract, Microsoft decided to use interfaces to
implement this feature. Because interfaces are contracts by their nature, they're a natural and
intuitive way to implement the requirement.
A service is denoted by the use of the ServiceContract attribute. You can decorate your
class definition with the ServiceContract attribute, but it makes much more sense to add the
definition to the interface instead. Because the Service has to implement the interface, applying the ServiceContract attribute to the interface definition has the effect of basically marking
the class as a ServiceContract. Although it would be a bit of an oversimplification, if I state
that the only difference between a WCF Service class and any other .NET class was that the
WCF Service class had to implement a corresponding interface, and that either the class or
the interface was decorated with the ServiceContract attribute, I am making a true statement.



Objective 3.1: Create a WCF service

CHAPTER 3

177

Besides decorating the class or interface definition with the ServiceContract attribute, the
only other necessary code requirement is that each method you want the service to provide
has to have the OperationContract attribute decorating it. Again, you can do this in the interface definition or you can do it on the actual method, but for several reasons, it makes more
sense to do so on the interface definition.
You will likely need to use custom types in your applications. In order for these types to be
used in WCF, they need to be serializable. The most common way this is accomplished, particularly with respect to this exam, is by decorating the type with the DataContract attribute.
Assuming that you changed the names from IService1 and Service1 to ITestService and
TestService, respectively, the default layout of each is shown in Listings 3-1 and 3-2.
LISTING 3-1  Contract definition
[ServiceContract]
public interface ITestService
{
[OperationContract]
string GetData(int value);
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);
}
LISTING 3-2  Class definition
public class TestService : ITestService
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite == null)
{
throw new ArgumentNullException("composite");
}
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
}

You will modify this code sample next, but first review a few of the core components:
■■

178

Notice that the ServiceContract and OperationContract attributes decorate the interface members, not the service members. You can define those attributes on the service
and service members instead, but that limits reuse, couples the contract with the
implementation, and creates several other undesirable consequences.

CHAPTER 3

Designing and implementing WCF Services

■■

■■

The interface defines each aspect of the service, and the service in turn implements the
interface just as it would any other interface that you would typically work with.
Although not illustrated in the code, you can certainly have methods that are defined
in the service that are not defined in the interface, but they are not accessible from a
client application. Similarly, you can have members defined in the interface that are not
decorated with the OperationContract attribute, but if they are not decorated accordingly, they aren’t part of the service as far as the rest of the world is concerned.

Other than the Interface definition, the most important key elements are the
ServiceContract and the OperationContract. These attributes differentiate a WCF Service class
from a standard .Net class. At the same time, saying they are the most important components
is a bit misleading in the same way that saying the engine and transmission are the two key
elements to a car. Much less important elements, such as the ignition, don’t necessarily have
to be there for something to be considered a car, but if you build a car, you want to have an
ignition. Tires are another element you need; they aren’t absolutely necessary for something
to meet the definition of a car, but any discussion of car building (or a certification exam covering cars) will likely have some mention of them.
Two elements that don’t technically have to be present for something to be a WCF Service,
but that you’ll frequently find yourself dealing with, are FaultContracts and a serialization
format, which for the purposes of this exam, are likely be the DataContract. A small digression into a discussion of endpoints is necessary to bring these components all into the proper
context.
EXAM TIP

On the exam, if you see a custom data type, remember that you must be able to serialize it.
As such, the class definition should be decorated with a DataContract attribute or another
serializer type. Custom exception types can also be presented. These should be decorated
with a FaultContract attribute.

Endpoints
When dealing with a WCF Service, one item you must be aware of (even if you don’t know it
and have to use a discovery mechanism to find it out at runtime) is the service endpoint. If
you’re heading off on a trip, you need to know where you’re going. The “where” is the endpoint. You’ll frequently come across the expression “ABC” in WCF literature about endpoints,
which stands for the following:
■■

■■



“A” stands for “address”  Corresponds to the “where” component of the equation
and typically takes the form of a URI.
“B” stands for “binding”  Equates to the “how” of the transport process. If you
plan a trip to Seattle (or any other city that’s far away), part of the planning involves
how you plan to get there. You can choose a commercial airline, a chartered plane, a
helicopter, a car, a motorcycle, or even your own two feet. Each has clear benefits and

Objective 3.1: Create a WCF service

CHAPTER 3

179

costs associated with it. Bindings, which are critical components of endpoints, are the
equivalent of the vehicle. The hosting mechanism you use can limit what bindings are
available, but that’s only a limitation of the hosting mechanism as opposed to a limitation of WCF. Finally, the bindings are defined at the service level, and one service can
expose itself through several different bindings at one time. (This is one of the main
reasons why WCF is vastly superior to traditional .asmx web services or any of the other
previous remote communication technologies such as distributed COM [DCOM]).
EXAM TIP

Although custom bindings are something you need to be familiar with if you are planning
on working with WCF, anything more complicated than their simple existence is unlikely to
appear on the exam.
■■

“C” stands for “contract”  The interface that is defined on the service.

MORE INFO  FULL LIST OF WCF BINDINGS

There are several bindings provided for you by the framework. A full list of the out-ofthe-box bindings and a discussion about their features and limitations is presented at
http://msdn.microsoft.com/en-us/library/ms730879.aspx. However, if you find that none of
the available bindings is sufficient for your needs, WCF can be extended to employ custom
bindings (see Table 3-1).

TABLE 3-1  System-provided binding overview

180

Binding

Security

Session

Transactions

BasicHttpBinding

None,
Transport,
Message, Mixed

None

None

WSHttpBinding

None,
Transport,
Message, Mixed

None,
Transport,
Reliable session

None, Yes

WS2007HttpBinding

None,
Transport,
Message, Mixed

None,
Transport,
Reliable session

None, Yes

WSDualHttpBinding

None, Message

Reliable session

None, Yes

WSFederationHttpBinding

None, Message,
Mixed

None, Reliable
session

None, Yes

WS2007FederationHttpBinding

None, Message,
Mixed

None, Reliable
session

None, Yes

NetTcpBinding

None,
Transport,
Message, Mixed

Reliable session,
Transport

None, Yes

CHAPTER 3

Designing and implementing WCF Services

Binding

Security

Session

Transactions

NetNamedPipeBinding

None, Transport

None, Transport

None, Yes

NetMsmqBinding

None, Message,
Transport, Both

None

None, Yes

NetPeerTcpBinding

None, Message,
Transport,
Mixed

None

None

MsmqIntegrationBinding

None, Transport

None

None, Yes

If you think about these bindings taken together, it makes perfect sense. To communicate
with a service, at some point your client application needs to know where to direct the communication. It needs to know how it will communicate. And it will need to know what it can
communicate or do. Remove any one of these elements, and it’s hard to imagine how a service could be of much benefit other than to be used as a statically linked class library (which
defeats the whole purpose of distributed communication).

WCF processing pipeline
The next thing you need to understand is the WCF pipeline. You know that on one hand you
have a service that is being exposed. On the other hand, you have a client that is consuming
the service. So what happens in between? Directly or indirectly, a proxy class is created for the
client, and the class enables the client application to interact with the service’s methods. The
request is serialized and transferred through the protocol specified in the binding. It’s transported to a dispatcher and then handed off to the service. Any information sent from the
client needs to be deserialized for the service to be able to consume it, and the same thing
needs to happen in reverse. If your service returns a list of grades for a given exam, it needs
to accept some sort of identifier for the exam. After the service’s method is called and the
parameter is received and deserialized, the method needs to process the application’s logic
just as any other application does. It accumulates the response or responses, serializes them,
and sends them back to the client. The client gets the serialized data, deserializes it, and then
does something with it.
If you’ve worked with distributed communication technologies for long enough that you
remember some of the older implementations (think CORBA or DCOM), you might remember
that most end up being technology-specific. Imagine that you’re a company that has a sizable
investment in your services. Just to drive the point home, imagine that it’s the equivalent of
a total of 500,000 lines of C# code. If your application worked with only one technology, say
Microsoft technologies, you would likely run into problems with clients that used some other
technology and couldn’t consume your service. You would now have to either turn away the
business or write a port of your application to the other technology. Anything outside of a
simple application would mean a sizable investment in the new development. Every time you
made a change to one service set, you would have to make the same changes to the other



Objective 3.1: Create a WCF service

CHAPTER 3

181