An Overview of the WCF Extensions
Introduction
Recently I documented adding a WCF extension to CruiseControl.Net. Due to mono-requirements I had to do it in a way that I wouldn’t force an upgrade of the CruiseControl.Net source code to .Net 3.0 or 3.5. Here is the complete set of posts:
- CruiseControl.Net and WCF
- WCF Server Extension
- Cruise Control Contract
- Transporting Data via Data Contracts
- WCF Router
- Extending CCTray
- Configuring a CCTray Custom Protocol
- WCF Custom Protocol
This will be my last post in this series as I’m preparing to move onto some more work (adding some security extensions to CruiseControl.Net). However I thought I ought to add this final post just to wrap up what I have done.
Before WCF
Before I started adding the extensions CruiseControl.Net consisted of three main components:
- Server (whether as a service or running as the console app)
- Dash board
- CCTray (the client application)
These communicated in the following ways:
As you see .Net Remoting was the only way to communicate with the server, thus the client either had to use .Net Remoting or go via the dashboard.
Extension Points
The first change was to add some extension points to both the server and CCTray. This would allow me to add the WCF code without converting the rest of the application. With the extension points the system now looked like this:
I didn’t add any extension points to the dashboard as I’m planning on going directly from the server (the worker of the system) to CCTray.
WCF Extensions
Now that I had some extension points for communications, I added the actual WCF components. These consisted of a server-side WCF extension, plus a custom transport protocol for CCTray.
The server side extension used the new hooks in CruiseServer to start and stop/abort a WCF ServiceHost. I added a service contract, ICruiseControlContract, plus its implementation and a number of data contracts to allow data extract. The only thing that a server administrator now needs to do is configure the server to use WCF – which uses the standard WCF configuration for the following service/contract combination:
- Service: ThoughtWorks.CruiseControl.WcfExtension.CruiseControlImplementation
- Contract: ThoughtWorks.CruiseControl.WcfExtension.ICruiseControlContract
CCTray is a custom transport extension. I added transport extensions so other people can also build their own transport mechanisms if desired. The main points to a transport extension is they must provide implementations of ICruiseProjectManager and ICruiseServerManager. These implementations do most of the actual work in CCTray, and they are returned from factory methods in ITransportExtension. For the WCF extension I implemented these classes and passed on all the calls to the client code generated by svcutil.
There is no need to modify the app.config for CCTray as the bindings and endpoints are generated in the code from user input – making it even simplier for end-users to set it up on their machines.
Routing Messages
The final piece of the puzzle is a router to sit in IIS:
This is required for installations that already have IIS listening on port 80 and want to use HTTP transport within WCF. Without the router we would have to use a different port to listen for requests.
The router merely needs to be added to IIS (either in an existing .Net 3.0 application or in its own application) and then its web.config modified to point to the listening WCF extension (which can listen on any port or protocol it likes).
What’s Next?
That, in a nutshell, is the work I did to allow WCF to be used in CruiseControl.Net. The extension points are general and can be used for other, non-WCF extensions.
Now I haven’t quite finished the work on the WCF extensions – they are missing one important component. Currently I am not passing any user information around! This is a major issue as ForceBuild(), AbortBuild() and FixBuild() all need this information. However I haven’t figured out an easy, secure way of passing this information, so I’m going to leave it for the moment.
At the moment I’m working on fixing a few issues that have been raised in Jira to try and get a better understanding of the code. Once I have finished these I’m going to look into adding a security layer to CruiseControl.Net that is easy to configure, flexible to expand and yet powerful enough to handle any security scenarios.






I added these for testing purposes – mainly could I could find them easily in
Finally, we’re ready to actually make the web service do something. The diagram on the right shows my 
To start with I’ve added a new library to the solution that uses .Net 3.5 (so we can also use some of the nice Linq functionality). In this library I’ve added a class that implements