At its core WCF is the unification of a number of different
technologies. This unification has allowed WCF services to deliver feature-rich
components that have transactional capabilities, reliable messaging, transport
independence, and time independence. Microsoft has delivered a flexible set of
features that allows us to leverage it using a number of different techniques.
The Power of Unification
One of the most obvious benefits of WCF is the unified
programming model. This consolidation of programming techniques will translate
into increased productivity for all distributed systems developers. Prior to
WCF, the programmer who would be best suited for building ASMX services was not
necessarily the same as the developer best suited for building COM+ Enterprise
Service components. With these technology sets merging, developers will be
able to continue to gain strength developing services that have some
consistency to them no matter what features they are required to deliver.
Although this does not necessarily map back to one of the key SO tenets, it
does map back to the goals of any enterprise. When there is an opportunity to
create some type of synergy between the developer and their programming model,
the efficiency gains are potentially awesome.
Patterns for Message Transfer
WCF presents developers with the ability to use three
different messaging patterns: simplex, duplex, and request-reply. Simplex
communication provides true fire and forget capabilities when invoking WCF
services. This can also be seen commonly referred to as one-way
communication. This approach is used when asynchronous write-only services are
the design goal for that service. It might seem as though this capability
already exists with ASMX today through the use of Begin and End methods. These
methods do allow us to invoke a web service asynchronously, but the actual
result is still request-reply.
Another of the messaging patterns available is duplex
communication. This mode differs from simplex significantly. In this mode, we
have true asynchronous two-way communications. With WCF services, if a
consumer needs to use duplex messaging, it must provide a service that the WCF
service can invoke a callback operation on. The important fact to remember
here is the asynchronous nature of the communication. In simplex and duplex
communication, the consumer is not locked into waiting for a reply.
Lastly, the most common approach for invoking services is
request-reply. It is this technique that we find proliferating web-based
communications today. ASMX is exclusively request-reply, and WCF gives us this
capability as well. I have often heard that services must be asynchronous in
order for them to be scalable. It is true that remaining asynchronous has huge
benefits when discussing scalability. This knowledge does not change the fact
that most applications need immediate responses. One of the service-oriented
tenets states that boundaries are explicit. If you are building services
that provide no response, it becomes very difficult to determine the success of
our operation. Although the messaging patterns are all very flexible, I see that
most of the services being delivered require synchronous request-reply
execution.
Declarative, Imperative, or Configuration-Based
WCF has implemented broad flexibility in how you leverage
the features available. Many of the features can be used one of three ways:
1) declarative programming, which uses attributes to decorate portions of your
code, 2) imperative programming, which uses the object model to set properties
directly in the code you write, and finally, 3) configuration-based
programming, which gives you the flexibility to make changes at runtime. It is
important to note that not all features within WCF can be managed with any of
these three techniques; in some cases you are limited to one or two styles
based on the feature.
Developers should be practical when choosing between these
programming techniques. The most critical decision comes when you decide what
should be configuration-based. If you are looking for flexibility at runtime,
the configuration-based approach is your obvious decision. The decision to use
declarative (attribute driven) or imperative (object model driven) is largely a
matter of style.
Service Type Support
WCF provides support for three different types of services.
These service types are not necessarily unique to WCF. Similar types of
services could be delivered in any number of distributed programming models.
What WCF has added is additional types and contracts for supporting these
service types in different ways. The following are the three types of services
that can be written with WCF.
- Typed Services: These services use precise
parameterization when invoking a service method call and respond with a
well-defined type. Services of this type most often resemble remote
components and have limited flexibility when it comes to versioning.
- Un-Typed Services: An un-typed service will use XML to
transport the input parameters and the response output. These services
are the most flexible, but provide very little value back to the
consumer. Un-Typed services require a consumer to parse XML in order to
understand what it is that a service is returning. This type of service
does not adhere to the service boundaries are explicit tenet.
- Typed Message Services: This approach for designing
services is more message-oriented. In this approach, a custom type is
identified that will contain all of the required input parameters and yet
another type that will wrap the output parameters. This approach is often
referred to as RequestObj / ResponseObj, as these are the types of
objects that are often a result of these types of services.
WCF has delivered various features that support all of these
different service types. In the case of typed services, WCF provides out
parameters and byref parameters. This gives developers more flexibility in the
return types from a service, allowing for method designs that have multiple
responses. Un-typed services have had a new type added to the service model.
The System.ServiceModel.Message type gives developers the ability to create
messages that can be sent to WCF services that have a wide degree of
variation. Typed message services can have a WCF message contract added to the
custom typed message, allowing a developer to specify how a message is
formatted on the wire.
The Service Model
Most of what I have talked about to this point is made
possible because of the System.ServiceModel namespace. This assembly is the
application programming interface for all of the WCF features I will discuss
moving forward. The service model comes complete with a large percentage of
the features necessary for common distributed development tasks. That does not
mean that this is what you are limited to when programming with WCF. The
service model comes with numerous extensibility hooks that allow developers to
create anything from custom bindings to custom channel stacks.