I recently attended an excellent presentation by John Chapman about Windows Communication Foundation (WCF). Before seeing his presentation, WCF was this complete black hole to me. I made an honest effort to learn WCF with the Help files, but every time I thought I "got" it, then it seemed like I didn't. Whenever I tried to read a book about WCF, my eyes would glaze over. I knew it was something that I would need to learn sooner or later, but I was dreading it.
During John's WCF presentation, things clicked for me. I'm sharing the information I learned from him (good work, John!) so you can get up and running with WCF as well. You'll want to download John's code from the presentation, since it has good examples of what I'm talking about.
The basicsInterface creation
The Message class is the fundamental basis of WCF. It is a SOAP-centric class and is the basic unit of exchange in WCF. This does not mean that WCF only uses SOAP, but SOAP is a natural analogue to WCF, and WCF can be exposed as SOAP.
Each WCF service consists of these three major portions:
- Address: how do you reach this service?
- Binding: how do you communicate with the service?
- Contract: what input and outputs does the service have?
When building a WCF service, you start by defining an Interface. You do not need to do this (you can just write a class with the appropriate decorators on the various methods and such), but for the sake of maintenance and separation of concerns, you use an interface. While I am generally against the creation of interfaces with only one implementation, it seems to make sense in WCF.
In this interface, you decorate the interface with ServiceContract, which gives the contract name and namespace; on individual methods, you give them the OperationContract decorator. You can add the FaultContract decorator to a method to indicate what class will be provided in case of an error condition. You would then throw a FaultException<T> object within your code when you have such an error condition, and WCF will turn it into the right kind of error for the client.
Input and output is an interesting topic. All parameters and return values must be primitive types. You can define a data structure if you like, but it can only contain other data structures or primitives; at the end of the day, all of the leaves on the data tree will be primitives. If you need to define any classes as data structures, the classes should receive the DataContract decorator. This is important because WCF is designed for interoperability with non-.NET systems. Even when a .NET application consumes the service, if the developer has access to the interface (and therefore don't need to use the WSDL or to parse XML trees), they refer to the naming in the various decorators, not the CLR types themselves.
Once you create your interface, you go ahead and implement it.Hosting the WCF service
Hosting the WCF service can be done in a number of ways, including IIS, a console application, or a Windows service. Your code will instantiate the ServiceHost class, and then add instances of binding classes to it. Each binding class gets an address, a port, and a binding type that tells it how to expose itself (such as SOAP). Each binding can have individual security assigned it to if you need to keep people out.
One thing that is interesting is that binding defined in app.config do not need to be instantiated by your code; when your application sees the binding details in the configuration, it will automatically create the binding at runtime. Another interesting point is that the services are not tied to the main thread; if the application is blocking (for example, a console app currently waiting on Console.ReadLine()) the bindings will still service clients.Consuming the WCF service
Consuming the WCF service is also quite easy. If the service is exposed with a SOAP binding, you can import the WSDL; but if you want to work in a more "native" fashion, you can. If you can read the interface that was created (this is why separating the interface from the class is a good idea), you can create a ChannelFactory object and pass to it binding details to receive an IRequestChannel. You can then send the previously mentioned Message objects to the request channel (which sends Message objects in response) in order to call its functionality.
WCF is really not as confusing as it seems at first. The impression you get from the documentation and the books is that it's an awful mess. The reality is 10% of its functionality is enough for 90% of your work, and the rest of it is for special scenarios, such as if you have complex security requirements.
Now that I know the basics of WCF, I am no longer afraid of it, and I am willing to experiment with it a little bit.
More about WCF on TechRepublic
- Book reviews: Get up to speed on .NET's Windows Communication Foundation
- Windows Presentation Foundation: Another piece of the .NET puzzle
- White paper: Build a Queued WCF Response Service
J.JaDisclosure of Justin's industry affiliations: Justin James has a contract with Spiceworks to write product buying guides; he has a contract with OpenAmplify, which is owned by Hapax, to write a series of blogs, tutorials, and articles; and he has a contract with OutSystems to write articles, sample code, etc.
———————————————————————————————————————————-Get weekly development tips in your inbox Keep your developer skills sharp by signing up for TechRepublic's free Web Developer newsletter, delivered each Tuesday. Automatically subscribe today!
Justin James is the Lead Architect for Conigent.