Skip to main content

Wrap your existing business layer with WCF

[Update: 21-Jun-08, v0.2 released...more info here]

I've recently had some hands on exposure with WCF. My initial impressions are that its pretty slick. However I was pretty perturbed to learn how invasive WCF is - specifically the "DataContract" attributes required to control the entity serialisation.

When designing software I start in the middle - usually a vanilla interface that represents some activity - this activity is UI and Data layer neutral...its upstream clients could be a UI or equally a service, likewise I make no assumptions about the persistance (if any) that might be required. So I was pretty unimpressed to learn that to expose an activity via WCF I needed to retrofit some WCF specific attributes to my interfaces and data entities in order for them to be WCF friendly. This does not sit well with me. Suddenly a context neutral component needs to know that it *might* be part of a WCF service and therefore has to be attributed just in case it is....and what about my existing entities and interfaces - I've got to go and revisit these too? Arrrrghhh!

I had a scout around - WCF and its forerunner Indigo are not exactly shiny shiny new features these days...someone must have already fixed this or come up with an architecture that solves this...I got pretty close with Web Service Software Factory from the Patterns & Practice team and although I'm keen to look into this further it looked a fairly serious heavyweight bit of kit, maybe too heavyweight. There was some talk of customised serialisation and not using the DataContract attributes at all but I wasn't keen on this either - it was sidestepping all the WCF goodness it seemed. A forum posting mentioned this problem and offered an approach - mirror your business interfaces and entities with WCF versions and convert the entities between the WCF and business layers. I liked this as it meant my business layer remained neutral and "unpolluted" but I wasn't keen on the waste of a mapping call for each entity in the interface.

However I took the bait and decided that creating the WCF versions of interfaces and entities and the conversion to and from the business layer could be automated. Reflect the business interface to WCF enable, discover the interface methods and entities then blast them out as WCF versions using CodeDom....which I did...and the WCFServiceWrapper application was born!

What is WCFServiceWrapper?
WCFServiceWrapper is a .Net console application written in C# 2.0, VS2005. It can take any interface, extract the methods and entities and then generate the WCF versions including conversion code from the orginal entities and a default service implementation. Essentially it allows for a "vanilla" interface and entities to be exposed via WCF without having to write any code to do it.

Once the application has been run against the interface you wish to expose via WCF all that is required is to include the source code items generated in your project and configure the app.config and you are up and running. It is even possible to generate Visual Basic WCF source code (although I have not exposed this on the application; you would need to rebuild the application from the source code to enable VB output. In the next build I'll add a command line switch for VB - promise!).

The console application is built on a core assembly that does all the heavy lifting including...
  • Discovery of the interface methods and entities
  • Generation of the WCF code items. Includes rudimentary collection and generics support
  • Saving of the WCF code items
This layout has been specifically chosen to enable other "clients"; for instance an add-in to Visual Studio could utilise this assembly.

The source code is here (v0.2 on project distributor)


Using WCFServiceWrapper
To use the application you need to have a built version of the assembly that contains the interface and entities. The interface and entities must be in the same assembly.

Use the command line switches
/A:[assembly filename including path]
/T:[interface name] - the interface name does not need to include the namespace.

To contol the namespaces...
/NI:[wcf interface namespace]
/NE:[wcf entity namespace]

To control the output folders
Either
/O:[output folder for both interface and entities]
Or
/OIF:[output interface folder]
/OEF:[output entity folder]

The latter allows separate folders for interface and entities.

Finally...

/OF+ overwrites existing files (default)
/OF- will not overwrite existing files (error if file already exists)

Once the WCF code has been generated you simply include it in your WCF project.


Example project
I have included an example solution to demonstrate WCFServiceWrapper in operation. This example solution contains a "Business Layer" project I want to expose via WCF. A blank WCF project is also included to host the WCF code generated items.

Note: This example solution is written using VS2008. You will need to compile the solution before and after running the WCFServiceWrapper application.

The example can be found here (updated for v0.2 release on project distributor)
  1. Unzip the WCFWrapperExample
  2. Open and compile the solution
  3. Goto the WCFWrapper folder and run CreateWrapper.bat. This will create the WCF code items in the WCFWrapperExample\MyServiceLayer folder - you should have two items (interface and service implementation) in this folder and and new folder called Entities. Remember to "Show all files" on the solution treeview to see these new items and include them in the project.
  4. Next is to open MyServiceLayer\CopyAndPaste.txt and follow the instructions. Then press F5 - the WCFTestClient application should open and allow you to test the OrderWidget method.

Final thoughts
I wrote this application to save time because I have lots of existing interfaces I want to expose via WCF and I didn't want to manually enable this. I have tested the app on the types of interfaces I commonly use - please be aware it has not been extensively tested!

The design also accomodates extension - you can write your own implementations for type discovery, code generation and publishing by following the code and interfaces provided in the TypeWrapper.Core assembly.

Although I have released this application I cannot guarantee any kind of support - I've made the source code available so if it doesn't cope with a specific problem then you can have a go yourself at resolving the issue. As I encounter problems I will fix them and post updates - if you have a problem then let me know and I can certainly take a look but I'm not promising anything! If this is popular at all then it might be worth moving to something like CodePlex to actually keep the source moving via collaboration.

The bottom line is that I have a day job and this is just a little app I created to make coding easier - I hope it can do the same for you!

Comments

Anonymous said…
Thanks for posting this!

I agree that it's a bit nasty to force developers to mark interfaces as WCF in the source code.

I was wondering if you had come across any articles discussing how WCF contracts could be generated dynamically (i.e. a runtime version of your wrapper). The option to wrap or otherwise transform an interface in order to prepare it for communication via the WCF would be worth its weight in gold...
Anonymous said…
I was premature in my previous comment - a related post appears here:

http://www.codeproject.com/KB/WCF/RuntimeGen_WCF_Service_Ex.aspx

Thanks again for sharing your solution.

Cheers,
Jones.
Unknown said…
Thanks for the comment and the link to the dynamic WCF stuff.

The nearest thing to this that I know of is Spring.Net can automatically generate ASMX service endpoints from vanilla ones at runtime...I guess its just SOAP/Asmx stuff it can generate but I also guess its extensible so it may be possible to utilise this framework to provide WCF runtime components instead. link:http://www.springframework.net/doc-latest/reference/html/webservices.html

Cheers,

James
Unknown said…
Jones,

Looking at the link you posted to dynamic WCF runtime code it would be pretty easy to extend WCFServiceWrapper to do this too.

WCFServiceWrapper does handle complex/custom user entities and generics - something lacking from that codeproject generator (as the author acknowledges). You could take the WCFServiceWrapper type discovery stuff to extend the other project.

Future improvements I had planned were targetted at generating other service representations such as REST and automatically providing a service implementation to invoke IoC frameworks like Castle, Ninject or Spring to soft-wire individual service method implementations.
Unknown said…
First off, congratulations on the move.
Good blogs Wrap your existing business layer.

Sarah
xocai marketing

Popular posts from this blog

Configuration in .Net 2.0

11-Dec-2007 Update I've updated this post to fix the broken images and replaced them with inline text for the example xml and accompanying C# code. This post has been by far the most hit on this blog and along with the comments about the missing images I thought it was time to update it! Whilst recreating the examples below I zipped up the working source code and xml file and loaded this onto my Project Distributor site - please download it to get a full working custom configuration to play with! Just click on the CustomConfigExampleSource link on the right hand side, then the "Source" link to get the zip. We are in the process of converting our codebase to .Net 2.0. We've used Enterprise Library to great effect so decided that we should continue with this in the form of the Jan 2006 release which targets 2.0 and I've got the job of porting our Logging, Data Access etc wrappers to EntLib 2.0. ...And so far so good - the EntLib docs aren't bad and the migrati...

Walk-Thru: Using Wolfpack to automatically deploy and smoke test your system

First, some history... The advent of NuGet has revolutionised many many aspects of the .Net ecosystem; MyGet, Chocolatey & OctopusDeploy to name a few solutions building upon its success bring even more features to the table. I also spotted that NuGet could solve a problem I was having with my OSS System Monitoring software Wolfpack ; essentially this is a core application framework that uses plugins for extension ( Wolfpack Contrib ) but how to unify, standardise and streamline how these plugins are made available? NuGet to the rescue again - I wrapped the NuGet infrastructure (I deem NuGet to be so ubiquitous and stable that is has transcended into the software "infrastrucuture" hall of fame) with a new OSS project called Sidewinder . Sidewinder allows me to wrap all my little extension and plugins in NuGet packages and deploy them directly from the Wolfpack application - it even allows me to issue a new version of Wolfpack and have Wolfpack update itself, sweet huh...

Announcing FluentGeoApi - a C# wrapper to GeoAPI.com

I'm pleased to make public the fruits of my late nights.... FluentGeoApi ! I previously mentioned that I am working on a private/personal project - well it's got an element of geolocation to it and after a bit of internet research I found GeoAPI.com . In order to interact with GeoAPI I decided to write a fluent style wrapper over the top of it and I've just released v1.0.0.0, a .Net 3.5 C# library to take the pain out of making REST calls and dealing with the GeoJson wire format used by GeoAPI. It's not 100% coverage of the API but I plan on getting there ASAP...however I've implemented Create/Modify/Delete a user entity, Simple and Keyword Search which is enough to release it. If you are working with geolocation data/features in your .Net application I would check out GeoAPI.com - I've been really impressed with what if offers (and if you hit the api < 20,000 times a day it won't cost you a penny!) - hopefully you'll also consider using FluentGe...