[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...
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)
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!
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
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)
- Unzip the WCFWrapperExample
- Open and compile the solution
- 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.
- 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
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...
http://www.codeproject.com/KB/WCF/RuntimeGen_WCF_Service_Ex.aspx
Thanks again for sharing your solution.
Cheers,
Jones.
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
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.
Good blogs Wrap your existing business layer.
Sarah
xocai marketing