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

A.Jones 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...
A.Jones 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.
James Simmonds 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
James Simmonds 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.
xocai said…
First off, congratulations on the move.
Good blogs Wrap your existing business layer.

Sarah
xocai marketing

Popular posts from this blog

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?

Abou…

Resharper add-in idea - highlight IDisposable vars

[Update 18th July 2013]
@RobGibbens and Greg Hurlman picked up on this - Rob pointed out that there is an FxCop rule that can do this and Greg suggested a Visual Studio extension. I've had a quick look at the Visual Studio options and it looks like an "Editor Extension" is a good fit....hmmm, Project New, click...doh...dammit I really don't have time for this but it looks a fun little diversion! I'll update here if I get anything working.

[Original Post]
Had an interesting idea for a Visual Studio Resharper add-in the other day but don't have the time to implement it so thought I would put it out there...it might already exist (and hopefully someone can point me in the right direction) or someone will build it (Darren Voisey where are you?!).

The idea is very simple really - when you have a variable for an object that implements IDisposable it gets highlighted or a tell-tale is displayed to let you know it should be disposed or should be wrapped in a using sta…

Geckoboard Countdown Widget v2

v2 is here, now with added colours! This time using the RAG Numbers widget to display your date countdown - as you get nearer the date the number will change from green to amber then red.

The new url is: http://geckocountdown.appspot.com/rag/?date=2010-12-25&tz=0&msg=Days+to+Xmas!
Note 1: notice the new /rag/ path and the msg querystring param.
Note 2: the original v1 url still works


To use this on your Geckoboard add a new "Custom Widget/RAG Numbers" widget. By default the number will turn amber at 10 or less days to go and red at 3 or less days to go however you can change these with the querystring (see below).


Required querystring params
date: "yyyy-mm-dd" format, this is the target date to countdown totz: timezone offset in hours from GMT that you are in. Can be negative if you are behind GMT
Optional querystring params
msg: the label that appears next to the number of days (remember to encode spaces as +). The default is "Days Remaining" if you…