I spent a good part of the day, reading, absorbing and digesting Clemens Vasters wonderful introductory article on WCF, Introduction to Building Windows Communication Foundation Services . Although Clemens is someone who is incredibly capable when it comes to translating plumbing level concepts to regular programmers, it is important to remember that Indigo is not for plumbers but for everyone. Still, this article is so clear and pragmatic in walking you through the most basic building blocks of Indigo and putting them into a context that is really easy to grasp and follow, I am very happy that it is out there as a resource. I have finally spent some, but not much time, with Indigo code over the last few days, so I did have some context when I started reading the article. If you haven't touched code yet, I would recommend reading the article, playing with some of the available code samples and then go back and read the article again, much more carefully.
The following is in no way intended as a replacement for reading the article, but just a good hit list of key points that are my notes to myself.
My key take-aways from Clemens Vasters' intro to Indigo article:
- We currently have many great ways to build distributed apps: ASMX (with or without WSE), MSMQ, Remoting and Enterprise Services, but quite often their benefits are mutually exclusive and can't be combined.
- ABC of Indigo: Address - Where is the service, Binding - How to talk to the service, Contract - What does the service do?
- Mix & Match - A contract can have multiple bindings, a binding can have multiple contracts, a contract can be served up by way of multiple endpoints, etc.
- Creating Contracts: 2 ways - 1) start with WSDL and use the svcutil.exe tool to build a contract proxy (with app.config) to be used in your client app 2) write your service in a familiar language (eg C#/VB). (From my own work, there will be times when you will still want to create a proxy from services written this way...)
- In a contract you expose methods by defining interfaces (recommended over actual classes) and then methods within them. Anything that should be available to WCF needs to be marked declaratively - the interfaces get [Service Contract] while the individual methods are marked as [Operation Contract]. These integrate wiht local declarations of public/private/etc so that you can control external and internal exposure simultaneously.
- DataContracts define complex data types that you may need to transfer across the pipe
- The new XMLFormatter is used to serialize and deserialize for WCF. It is a little more locked down because there is some really interesting versioning support that you can build directly into your DataContract classes and if you mucked with the serialization, you could break the versioning support.
- The great debate: why does it look like RPC? So you can program in a familiar way. You are still NOT passing objects or callbacks delegates though - it is NOT RPC.
- If you want to really feel like you are programming for messaging, there are a number of ways to build messages, rather than programming in the object model way. Tags such as [MessageContract], [MessageHeader] and [MessageBody] are used in these methods. Clemens goes into detail on how to implement the various styles.
- When coding up the actual methods of the service, it doesn't need to be any different than regular coding, however you can add some more depth in here by applying Behaviors with [Service Behavior] and [OperationBehavior]. This will probably be most familiar to those with experience building Enterprise Services (which does not include me!) One example of a behavior is to implement transaction scope which you can do with amazing granularity.
- Binding binds the service to the address - this is a great way to perceive it.
- Hosting is not limited to IIS - I finally got to wrap my head around this one with WSE, so I was prepared for this!
- A service needs a service host. This can be created by WCF when you load up the class or you can create your own service host (using ServiceHost) to host the service inside your own process.
- Key (but not only) things that binding defines: Transport, Security, Reliable Messaging
- There are a bunch of preconfigured bindings. Here is a link to a list of them.
- Putting it all together, either in code or in a config file, you create an endpoint and within the endpoint, indicate the address, the binding and the contract by name. Elsewhere you can define and/or customize the bindings.
- Binding Requirements and Validations can be defined in the service itself. Then the service will only allow you to couple it together with bindings that meet those requirements.
- ALL of the above was all about services, however much of this knowledge will be applied to the client side as well.
- On the client side, you can reference a proxy to the service which will also come with a preconfigured config file (this is done by the svcutil.exe tool). Therefore, the implementation of WCF on the client side is really simple, or you can copy the metadata into the client code. Clemens points out that the latter is much more in the spirit of SOA.
- The client is an independent entity in the messaging world. It too, needs to follow the pattern of ABC.
- Hook the client code up to the WCF goo inside of your config file by using a ChannelFactory. In other words, the service's configuration info can be in your client's app.config and then in the client code, you can build a link to it.