One of the most inflexible aspects for distributed
development today is endpoint definition. Whether we are talking about the
tight coupling introduced by interface definition languages or the rigidity of
an ASMX endpoint, a service has very little flexibility once it is being
consumed. WCF has made some huge strides in this area. Endpoints are no
longer limited to a single transport or a single contract version. More
importantly, services are no longer limited to a single endpoint.
Anatomy of an Endpoint
The popular mnemonic being used to remember what an endpoint
is comprised of is: Endpoints contain the ABCs of a service. Specifically
the ABC portion of that statement is being used to reinforce endpoint
definition.
- A is for Address: A WCF service endpoint has a unique
address. Addresses are not necessarily something we have not seen with
distributed technologies all along. However, in the past this was one of
the only qualifying characteristics of an endpoint. In web services, the
address was a defined URI; with .NET Remoting, it would be a TCP address.
- B is for Binding: Bindings are a portion of the Policy
that a service and consumer have to agree on if they want to exchange
messages. This binding will contain the information to support the
features being exposed by the service. I will cover bindings in more
detail in the following section.
- C is for Contract: There are a number of different types
of contracts with WCF. The primary contract that defines service behavior
is the service contract. This is analogous to the portType within WSDL
today. This also rounds out the Policy definition of a service.
Why Is This Better Than What I Have Today?
Endpoint definition up until now has had little to no
flexibility. With the introduction of WCF, multiple endpoints can be defined,
allowing service consumers to satisfy a variety of application requirements.
If you have a .NET to .NET scenario where you would like to leverage TCP
transports and Binary message encoding, then go ahead. Of course, you could do
this before with .NET remoting, but what you could not do is have a parallel
endpoint that was exposed via HTTP and used text-based SOAP encoding to service
a Java client. The flexibility for service invocation has the potential to
truly allow services to use policy-based communication. If you wanted to do
this today, you would likely have two versions of the service, which would lead
to an increased maintenance costs.
Here is an example of an endpoint definition that is hosted
in IIS. Use some creativity to envision a scenario where I might want to
communicate to this service with a client on the same machine and use named
pipe transports. Also notice that when hosting in IIS the address can be left
blank and it will default to the location where it is hosted within IIS. This
is not much different than what we would do in ASMX today. In the case of the
configuration below an appropriate address would be
http://localhost/Service/FamilyGuyQuotes.svc.
IIS Hosted Service Config
<system.serviceModel>
<services>
<service serviceType="FamilyGuy.FamilyGuyQuotes">
<endpoint address="" bindingSectionName="basicProfileBinding"
contractType="FamilyGuy.IFamilyGuyGoodies"/>
</service>
</services>
</system.serviceModel>