Archive

Archive for the ‘WCF’ Category

What Are APIs Anyway?

February 19th, 2010

What are APIs anyway?

Everyone’s heard of APIs these days.  Facebook has them, Twitter has them, Hotmail has them, Microsoft Office has them, Windows has them, Mac OS has them, pretty much everything has them.  I’m going to try and explain in simple terms, but also, almost by contradiction, in detail, what an API really is.  I’ll try and explain why SOAP isn’t how you clean yourself, and how being restful isn’t the same as being lazy.

APIs aren’t new, in fact, APIs are really really old.

Let’s start with a really simple definition.  API is an acronym and it stands for “Application Programming Interface”

To steal the current definition from Wikipedia “An application programming interface (API) is an interface implemented by a software program to enable interaction with other software, much in the same way that a user interface facilitates interaction between humans and computers. APIs are implemented by applicationslibraries and operating systems to determine the vocabulary and calling conventions the programmer should employ to use their services. It may include specifications for routinesdata structuresobject classes and protocols used to communicate between the consumer and implementer of the API.”

That’s a mouthful.  So to translate that into English, an API is a pre-defined set of “stuff” that allows one program to “talk” to another program.  This “stuff” is normally a set of “functions” that another program can call which makes the program being called do something.  Sometimes that other program is really just another part of the same program, and sometimes it’s a different system on a different machine in a different country.  That something is normally described in some kind of documentation, written somewhere, by someone.

If this sounds really vague it’s because in the real world, it really is.  Some of the first “APIs” involved dropped text files into directories on a computer that another program would watch for a read from, and subsequently do “something”.  Arguably the most widely used API is the one that we use to write software for Windows (the Win32 API) and by contrast, that’s a C++ library of code that you can only call if you’re a programmer.  In the real world, we’ve tried to solve some of this ambiguity by standardizing the way APIs work around a few common bits of technology; both for our own sanity and to hopefully help software all just kind of work together.

A lot of APIs are code libraries called by other code libraries to do a specific task.  Microsoft released DirectX to deal with 3d graphics, OpenGL offered an open alternative.  Microsoft released the Windows API for Windows development; Apple released Carbon and Cocoa to program Mac OS.  That said when you hear about or discuss APIs casually, what you’re probably thinking about are actually “Web APIs”.

Web APIs

A Web API is an API like anything else, except it’s designed to work over the web.  As a result of this, since about 1994, there have been a number of efforts by a number of people (yes, that vague again!) to standardize the way systems communicate over the internet.

At first, everyone kind of invented their own way of communicating over the internet, people would connect to a server on some port (a port is just a pre-defined “way in”) and send some random pre-defined data in there, and that would make the computer at the other end do something.  Every API was different, and every time that you needed to talk to a different system, you had a really steep learning curve to work out how to talk to every application you wanted to integrate with.  It was a bit rubbish really.

So in 1998 a bunch of really smart people (Dave Winer, Don Box, Bob Atkinson, and Mohsen Al-Ghosein) got together and came up with SOAP (“Simple Object Access Protocol”).  SOAP is a big bunch of XML that was designed (and ratified) as a standard language that every different system could understand. SOAP is often also referred to as “web services”.

Basically it was designed to reduce the learning curve of learning the details of each system.  So now, if Timmy wanted to talk to Peters shiny new web application, he could point his developer tools at a standard location (something called a WSDL (web service description) document) and he could just ask Peters web application what it did, and how he could use it.

SOAP was actually pretty good and solved a lot of problems and is still widely used today.  It really made waves by helping Microsoft software work pretty well with Java software and everyone was happy.

Almost.

See, because SOAP was solving a lot of big problems in freaking huge enterprise systems, it had a lot to be concerned about; lots of security, lots of encryption, lots of authentication.   That meant that the SOAP “language” was pretty big.  As an example, here (stolen from Wikipedia again!) is the SOAP message that would be sent across the internet to get the current stock price of IBM, from some cool stock price giving web service.

POST /InStock HTTP/1.1

Host: www.example.org

Content-Type: application/soap+xml; charset=utf-8

<?xml version=”1.0″?>

<soap:Envelope

xmlns:soap=”http://www.w3.org/2001/12/soap-envelope”

soap:encodingStyle=”http://www.w3.org/2001/12/soap-encoding”>

<soap:Body xmlns:m=”http://www.example.org/stock”>

<m:GetStockPrice>

<m:StockName>IBM</m:StockName>

</m:GetStockPrice>

</soap:Body>

</soap:Envelope>

People soon started thinking “Look at all that crap! What’s it all for! Why do I need it?! There’s lots of overhead here!  It slows me down!” and everyone thought “oh actually, well said” and RESTful web services were born.

REST is yet another stupid acronym that actually doesn’t count as an acronym because it uses random letters but developers think is either cool clever or funny.  What it claims to mean is “REpresentational State Transfer” and was largely both a reaction to the complexity and overheads of SOAP, but also being designed by Roy Fielding (one of the authors of the “Hypertext transfer protocol”, the silly http:// bit you type in a browser) it was conceived as an API model that was “closer to the nature of the web”.

What this means to us lay folk, is that while SOAP can technically be used over other protocols (it’s not bound to http), and as such has to bake in security and authentication models into its protocol, REST is designed specifically for the web, it doesn’t work without the web, and it wouldn’t make any sense without the web.  Fielding basically decided that “the web does all of that stuff anyway”, we have security via https / SSL certificates, we have semantics that describe getting and pushing data in the HTTP headers (HTTP headers explain what you’re trying to do to the server you’re connecting to, for example, you use GET for getting stuff, POST and PUT for doing stuff), so let’s just use that and be done with it.

As a result of this way of thinking, REST is a simplified and less general Web API pattern, not concerned with infrastructure like SOAP is.  I’ll convert the above stock price example into a REST example below.

GET /Stocks/Price/IBM HTTP/1.1

Host: www.example.org

Content-Type: application/xml; charset=utf-8

Done.

Basically, REST takes out all the fluff, an decides that if you want to get a stock price for IBM, just make a GET request to the URL http://www.example.org/Stocks/Price/IBM and let the web server at the other end work out what to do from the URL.

The above example would probably return an XML document that looks like this.

<stocks><stock name=”IBM” price=”3.45”/></stocks>

People have started to gravitate towards REST due to its simplicity.  There’s lots of other stuff a RESTful web service should do, it should provided you with all the information that a computer would need to go through a process, just like a user interface gives the user all the information they need to click through a process, but fundamentally it’s simple and leverages the existing semantics of the web to its advantage.

Ok, Give Me One Of Those!

So now we know what an API is there to do (let two systems talk to each other) and how they do it (as a general rule, either via SOAP or RESTful services) and we know that everyone else has one, let’s get one of our own.

There are plenty of tools available in pretty much any programming language to make making creating APIs pretty easy.  There are plenty of design concerns to take into account when building an API but in my opinion, the way to approach the problem is to work out what your users really want to do with your application, website or platform, and let them do it.

A good API lets another programmer talk to your system using terms that he understands, so take the time building up a glossary of your business terms vs. what the public understands those concepts to be.  Don’t build API methods that look like:

/PaymentResolutionProcess/PaymentResolveTable3/Resolve/EntityId/123

because it means nothing to anyone, instead, build a bunch of methods that make sense for people to use, the above example could look like this instead:

/Payment/MakePayment/123

Watch your language, and build sensible interactions with your system.  Don’t make APIs for stuff that isn’t going to be used, and where possible, just have the APIs call the same code that your website does.

Get this right, and you’re on a gradual but successful road to calling your “website” a “platform”.

Creating a WCF Proxy to talk to Magento

October 5th, 2009

I got a message from a friend who was struggling to do an integration piece with the Magento eCommerce Platform using the SOAP endpoint available at http://yourserver.co.uk/api/v2_soap?wsdl.

He brought an interesting problem to me, namely that the WCF svcutil executable (and built in Visual Studio 2008) was failing to generate any proxy code when supplied with a seemingly valid wsdl.

I did a quick test and managed to instantly reproduce the error.

Weirder still, when using the “old” .Net 2.0 add web reference method rather than the .Net 3.0+ “Add Service Reference”, the framework managed to create a non-WCF reference just fine.

Dropping down to the command line I saw some unusual messages being displayed by svcutil.exe:

c:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin>SvcUtil.exe http://yourserver.co.uk/api/v2_soap?wsdl
Attempting to download metadata from ‘http://yourserver.co.uk/api/v2_soap?wsdl’ using WS-Metadata Exchange or DISCO.

(Lots of error messages here…)

Error: Cannot import wsdl:portType
Detail: An exception was thrown while running a WSDL import extension: System.Se
rviceModel.Description.XmlSerializerMessageContractImporter
Error: The ‘ ‘ character, hexadecimal value 0×20, cannot be included in a name.
Parameter name: name
XPath to Error Source: //wsdl:definitions[@targetNamespace='urn:Magento']/wsdl:p
ortType[@name='Mage_Api_Model_Server_V2_HandlerPortType']

Error: Cannot import wsdl:binding
Detail: There was an error importing a wsdl:portType that the wsdl:binding is de
pendent on.
XPath to wsdl:portType: //wsdl:definitions[@targetNamespace='urn:Magento']/wsdl:
portType[@name='Mage_Api_Model_Server_V2_HandlerPortType']
XPath to Error Source: //wsdl:definitions[@targetNamespace='urn:Magento']/wsdl:b
inding[@name='Mage_Api_Model_Server_V2_HandlerBinding']

Error: Cannot import wsdl:port
Detail: There was an error importing a wsdl:binding that the wsdl:port is depend
ent on.
XPath to wsdl:binding: //wsdl:definitions[@targetNamespace='urn:Magento']/wsdl:b
inding[@name='Mage_Api_Model_Server_V2_HandlerBinding']
XPath to Error Source: //wsdl:definitions[@targetNamespace='urn:Magento']/wsdl:s
ervice[@name='MagentoService']/wsdl:port[@name='Mage_Api_Model_Server_V2_Handler
Port']

Generating files…
Warning: No code was generated.
If you were trying to generate a client, this could be because the metadata docu
ments did not contain any valid contracts or services
or because all contracts/services were discovered to exist in /reference assembl
ies. Verify that you passed all the metadata documents to the tool.

Warning: If you would like to generate data contracts from schemas make sure to
use the /dataContractOnly option.

c:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin>

So I did a little digging through the WSDL and found an undocumented bug in Magneto’s schema.

First I saved a local copy of the WSDL and used visual studio to reformat the document into some sort of readable state, then I had to make a few corrections to the WSDL to allow SvcUtil to correctly parse the malformed document.

Change 1:  Replace a badly encoded apostrophe – I removed the “’s” from the following operation definition…

<operation name="customerGroupList">
<documentation>Retrieve customer’s groups</documentation>
<input message="typens:customerGroupListRequest"/>
<output message="typens:customerGroupListResponse"/>
</operation>

Change 2: Replace a trailing space in an operation name

<message name="catalogProductGetSpecialPriceRequest">
  <part name="sessionId" type="xsd:string"></part>
  <part name="product" type="xsd:string"></part>
  <part name="storeView " type="xsd:string"></part>
</message>

If you look carefully at the above message definition, you’ll notice that name=”storeView “ contains a space, making the wsdl invalid.  Remove the space so it reads “storeView”.

With these two errors corrected, SvcUtil had no problem generating an appropriate WCF proxy from the corrected wsdl file.

Magneto will hopefully fix this error in the WSDL, but until this time, it’s probably quite safe to follow these steps to generate your own proxy.

To reproduce:

  • Go to http://yourserver.co.uk/api/v2_soap?wsdl and save the contents of your file to the local disk (c:\test\main.wsdl)
  • Open the file in visual studio, and reformat the document for readability (CTRL+K, CTRL+D).
  • Remove the apostrophe from the documentation tag for the customerGroupList operation.
  • Remove the space after the name=”storeView “ in the catalogProductGetSpecialPriceRequest message definition.
  • Open a command prompt and enter
  • c:\test>c:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\svcutil.exe main.wsdl
  • SvcUtil will produce two files, Magento.cs (your WCF proxy) and output.config, your endpoint configuration.

XNA Game Development: Coding For Multiplatform Multiplayer 2

March 12th, 2009

It occurs to me that I wasn’t thinking straight when I wrote the previous entry regarding my reluctance to use .Net 3.5 SP1 in ‘Encounters’ for hybrid networking.

In a clearer state of mind, it occurs to me that because only the Windows version of the game is going to use the WCF networking implementation, that only the Windows version of the game will require the 3.5 SP1 version of the framework as a result.

The Xbox 360 appears to use a version of the Compact Framework 3.5, however it’s worth noting that 3.5 is a binary compatible set of additional assemblies that run in the .Net 2.0 environment.

What this effectively means is that I can use functionality in 3.5 SP1 (specifically the ability to serailize objects that aren’t marked as DataContracts or Seralizable) for the Windows version of the networking stack without contaminating the code of the game and preventing it from running on a 360.

Even better, it means I don’t need to mark-up my data model with any kind of attributes to support network play on Windows and I shouldn’t need to use a dubious set of byte array wrappers for data that can be typesafe, effectively letting me maintain a “purer” game model.

I’ll move my development environment to 3.5 SP1 and test this theory later, but I suspect I can simplify the networking stack on windows without the need for any messy hacks because of SP1.

Sometimes sleeping on a problem really is the answer; I was about to do something pretty stupid.

XNA Game Development: Coding For Multiplatform Multiplayer

March 12th, 2009

I’ve jumped right in to the deep end with my game project (which is going under the working title of “Encounters” – I needed to call the solution something!) and one of the core design goals of the project is the multiplayer focus of the game.

I’m a huge fan of Id SoftwareJohn Carmack is probably my favourite “celebrity computer programmer”.  He’s incredible smart and consistent and has made some of both the most influential and my own favourite games.

Standing on the shoulders of giants - The “Quake” model

I’ve always thought the “Quake model” of single player and multiplayer game development to be a good one.  For those that don’t know, one of the simple design tenants of the Quake engine is that everything is a multiplayer game.  When you play the campaign in the original Quake what the game actually does is start a local game server which you then connect to.  Due to the proliferation of the Quake engine and other engines that have been inspired by it’s design this became quite a common way to build first person shooters with multiplayer support from the offset.  It reduced the implementation of multiplayer to simply having a second player connect to the active session.

Standing on the shoulders of giants, I’ve decided that this is the model I wish to follow for Encounters, especially seeing as the primary work-in-progress game design desires 4-player coop as the main campaign (with NPC assistants if you play with fewer humans).  Because of the way supporting multiplayer from the offset effectively means that all the games “thinking” is done in the server component (collision detection, cheat prevention, state management..) I decide that it’d be the best place to start the implementation.

Prototyping

So far so good, I spent an hour or two last night designing a simple state managing game server and retrofitting it to my previous prototype (an arena with a player-controlled unit moving around it) and moving all the logic and validation to the server side.

At this point the “game server” was a singleton class that the game accessed though a fake “proxy” class (left empty for eventual network implementation) and it worked pretty well.  The collision detection worked on the “server side” when the server was running in the same application domain and as a proof of concept everything was quite sound. I’m still left facing a few issues surrounding the frequency of syncing with the server and client side prediction, but they’re all relatively well solved problems in gaming (and there’s certainly some prior art to take inspiration from in XNA tutorials around the web).

Building a network stack

Once the proof of concept was working I started looking into the networking support provided by XNA and hit the mother of all roadblocks.  Because I’m targeting both the 360 and Windows, networking becomes significantly more complicated.  See, Microsoft offer no direct network access on the 360, via XNA, or even to their licensed partners (internet hearsay claims).  They provide Xbox Live APIs as part of the XNA framework however, which seemed like a decent solution until I realised that these networking APIs function only on a 360 as part of Xbox live.

Not so multiplatform really

So I’ve started thinking around the problem.  I do a lot of work with WCF in my day-job writing distributed systems so my obvious inclination was to provide a WCF client-server architecture for the Windows targeted version of the game.  This adds an additional set of issues.  For a start it looks as though the WCF assemblies (System.ServiceModel) are probably not available on the 360.  You’d think that’s not much of a problem if you’re going to use the Live APIs, but then you realise that if you’re using a version of .Net 3.5 prior to the first service pack, you need to annotate any classes you want to transfer via WCF with the DataContract attribute.  Which is in the System.ServiceModel namespace.

I’m not sure (as I currently don’t have a subscription to deploy my test code onto my 360) what version of the framework the 360 is running, but I’d hazard a guess that it’s pre SP1.  I’m going to have to further research this problem, because if you can use SP1 on the 360 (which supports serialization without any attributes on the classes) then we’re home free.

Multiplatform networking code using Inversion of Control

In the interim I’ve devised a cunning solution (or perhaps workaround, I’m not sure).  See, all of these issues lead me to need two entirely separate network stacks for my game.  One that supported the Windows, and the other that supported Xbox live, without contaminating my data model with mark-up that’s useable in only one or the other of the stacks.

Castle Windsor to the rescue.

This is purely speculative as I haven’t attempted to implement the 360 network stack yet, but I intend to use the Castle Windsor IoC (inversion of control) container to load a separate network stack at runtime, depending on the platform.

My idea is that the game knows about two interfaces IGameServer and IGameServerConnection.  I then create two entirely separate assemblies, one with the networking code for the PC, the other with the Live networking code.  The PC version contains a class called WcfGameServer which implements IGameServer (I’ve already written this code), and a class called WcfGameServerConnection which implementes IGameServerConnection (and acts as a hand crafted WCF proxy).  The 360 implementation will feature XBL counterparts to these classes.

As far as the game is concerned, it’ll use the Windsor container to load an instance of IGameServer, call the StartListening(); method, then use Windsor to load an instance of IGameServerConnection() and call JoinGame() on that connection.  This way, the specific networking implementation is entirely removed from the game and hidden behind these two simple interfaces.

I’ve currently got a good way through implementing the WCF version of this model though I’ve hit a few snags on the way.  Because I’m deliberately developing in a pre-SP1 environment for the sake of this exercise, WCF doesn’t like serializing the game model to send over the wire.  As a result I’ve had to produce an inelegant hack to work around my desire to keep the System.ServiceModel assembly reference clear of my game model.

Trying to keep it light

I’ve marked up my model with Serializable attributes (.NET 1.1, that’ll be fine) and inside my WCF implementation of IGameServerConnection I’m marshalling all my data into byte[]’s before sending it over the wire.  This isn’t ideal as it requires the WCF implementation to manually deserialize the byte[]’s into their correct data types in the service implementation and the client library, but it does work.  Unfortunately at the moment these byte arrays are being stored as XML before being sent over the wire (as is the default WCF way) so I’m going to need to force WCF to binary serialize all it’s data rather than bloat my packets (and as a result, the game latency).  I’m using Net.Tcp so it’s pretty lightweight as far as protocols go but I suspect I’ll need to do some additional fine tuning to make the WCF implementation viable.

Either way, I’ve got a good feeling about the model, subtle hacks aside, and I think this is quite a good way to target both platforms with minimal impact to your game code.

So this is day 3 of development (I’m sure I’m going to loose count pretty quickly).

[Footnote]

It occurs to me that I got a few fundamental things wrong when this post was originally written regarding the requirements for .Net 3.5 SP1.  These mistakes almost complicated the design of the networking stack.  Read more in my follow up here.

Using C#, Inversion of Control and WCF to produce a generic host for use in distributed systems.

February 21st, 2008

.Net 3.0 & 3.5 provides a number of techniques for you to author your own distributed architectures and I’m going to attempt to explain a technique that “worked for me”, allowing me to write a reliable, testable, service based application using the Windows Communication Foundation (WCF).

The goal of this little project is to create a multipurpose standalone server application that can host any code you wish, using WCF to provide other applications access to the code.  The server application should have no idea what it’s hosting, nor be concerned with it.  New services should be installable in to the service host by configuration tweaks alone.  This will result in a low impact standard method to expose API’s and web services to either external or internal applications using just configuration settings.

 

Pre-Requirements

Throughout this example I’ll be presuming that the reader has a strong grasp of .Net. C#, and Microsoft technologies.  I’ll also touch on nUnit testing and the Castle projects IOC container Windsor, so exposure to either or both of those products would be advantageous.  That said, for the most part, this should just be compile, configure and go.

Castle Windsor: http://www.castleproject.org/castle/download.html
NUnit: http://www.nunit.org/index.php?p=download (or mbUnit if you wish…)
and obviously Visual Studio 2005/2008.

 

Sample Architecture

The following is a pattern that I’ve found to work very successfully:

  • /ServiceApplication
    • /ConsoleHost
    • /SystemService
    • /ServiceContracts
    • /ServiceImplementations
    • /Test_SystemService
    • /Test_ServiceImplementations
    • /CommunicationManager
    • /Installation
  • /ClientApplication
    • /Model
    • /DataManager

We’ll take a look at the client application later, but first a rough outline of the projects that the ServiceApplication consists of.

ConsoleHost is designed to be an exceptionally thin wrapper to provide a console view on the service, it’s concerned only with user interaction and should use CommunicationManager for all of the legwork.

SystemService is an equally thin wrapper around CommunicationManager providing an installable service wrap for your application.

ServiceContracts is an assembly that should contain ONLY the WCF service contracts (C# interfaces) that you intend to make accessible remotely.  You should expect to share this compiled assembly with any client implementations, so ensure this is dependency free (which really shouldn’t be a problem so long as you ensure that you only store interfaces in this assembly).

ServiceImplementations should consist of the ServiceApplication specific implementations of the interfaces defined within ServiceContracts.

Test_SystemService is designed to store unit tests that make use of WCF to connect to the running ServiceApplication, and Test_ServiceImplementations should contain unit tests designed to test the ServiceImplementations directly.  Having these two similar test projects allows you to troubleshoot connection related errors during development independently of code logic related errors.

The CommunicationManager does the brunt of the work, constructing WCF endpoints and maintaining them throughout their lifecycle.  This assembly takes care of the opening and closing of listening services.  It’s constructed of a few key components I’ll detail later.

Installation is reserved for an Installer of your choice, preferably one that can deploy and install Windows Services (WiX or old fashioned MSI projects, I’m looking at you).

I’m not going to go into great detail regarding the SystemService (it’s a standard windows service which calls the same methods the console host will), nor the unit tests or installer.  I’m also not going to try and explain the intricate details of the configuration of WCF, there’s a wealth of resources available online on this topic.  I will however supply some example configuration- enough to make the code functional.

 

Service Functionality

Define Your Service Contracts

The simplest way to start this project is to define an interface in C# which should describe a few basic operations that you wish to make available as a service (the WCF Service Contract).  I’ve distilled this down into an example I’m calling IExampleContract, the contents of which are:

using System.ServiceModel;

namespace DEJW.ServiceContracts
{
    [ServiceContract(Namespace = "http://namespace/", Name = "Example Service")]
    public interface IExampleContract
    {
        /// <summary>
        /// Returns the uniqueIdentifier supplied back to the calling application.
        /// </summary>
        /// <param name=”uniqueIdentifier”></param>
        /// <returns></returns>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        string Handshake(string uniqueIdentifier);
    }
}

 

Define the ServiceImplementation tests

For the sake of following good “XP” practice, the next step should be constructing a simple unit test for the methods you wish to define, and then author the implementation top down.  For the above simple “Handshake” method, the following nUnit test should suffice:

[Test]
public void HandshakeWithSimpleString()
{
    string testString = “Hello World!”;

    ExampleContractImpl impl = new ExampleContractImpl();
    string response = impl.Handshake(testString);

    Assert.AreEqual(testString, response);
}

Write the ServiceImplementations to fulfil the tests

With my (failing, no code!) unit test in place, I’ll now write the code to pass the test.  The implementation should go into a ServiceImplementations project (because when you hand your ServiceContracts over to the consuming application, you’d not want to pass over the service implementation to go with it…).

using DEJW.CommunicationManager;
using DEJW.ServiceContracts;

namespace DEJW.ServiceImplementations
{
    public class ExampleContractImpl: IExampleContract, IPlugableService
    {
        #region IExampleContract Members

        public string Handshake(string uniqueIdentifier)
        {
            return uniqueIdentifier;
        }

        #endregion
    }
}

You may have noticed that the implementation features a rogue little interface called IPlugableService that doesn’t appear to need implementing.  This is a concession to the Castle IOC framework and I’ll elaborate on its use in the section on CommunicationManager.


Communication Manager

The CommunicationManager assembly consists of a few key components. 

  • HostManager, responsible for opening and closing WCF endpoints as per the configuration in app.config.
  • IOCFactory, a wrapper for the Windsor containers that helps quickly load a concrete implementation from a configuration value and assembly name.
  • IPlugableService interface, an empty interface used that must be implemented by our service implementations in order for the Windsor container to identify them.
  • IPlugableServiceFactory, an configuration parsing library that inspects configuration and instantiates instances of all the IPlugableServices’ defined in app.config.

I’m not going to go into great detail regarding HostManager, most of the code was adapted from various Microsoft WCF samples with a few generic collections tacked on and a couple of wrapping methods.  There’s nothing high-tech here, it just works.

Usage is very simple:

_hostManager = new HostManager();
_hostManager.AddServiceContracts(PlugableServiceFactory.RetrieveCollectionOfPlugableServices());
_hostManager.StartListening();

As long as your configuration settings are correct, magic happens here.

The key method there is PlugableServiceFactory.RetrieveCollectionOfPlugableServices().  This method loads and traverses the Castle Windsor configuration, and then loads by name every instances of IPlugableService it finds in the config file.  HostManager then uses a typeof on each of these loaded IPlugableService to create a instance of their concrete type, ignoring IPlugableService entirely.  IPlugableService is an interface in place simply so we can tell Windsor what to do.  HostManager then configures the concrete classes as WCF ServiceHosts using the configuration specified.

Configuration Settings

Ensure the following is included in your app.config file:

<configSections>
  <section name=”castle” type=”Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor” />
</configSections>

<castle>
  <components>
    <component  id=”service1″
                service=”DEJW.CommunicationManager.IPlugableService, DEJW.CommunicationManager”
                type=”DEJW.ServiceImplementations.ExampleContractImpl, DEJW.ServiceImplementations” />

    <component  id=”service2″
                service=”DEJW.CommunicationManager.IPlugableService, DEJW.CommunicationManager”
                type=”DEJW.ServiceImplementations.ExampleContractTwoImpl, DEJW.ServiceImplementations” />
  </components>
</castle>

If you look carefully you’ll see why IPlugableService is important; the Windsor components will attempt to instantiate your components as instances of that empty interface.  The type attribute points to “NameSpace.ConcreteClass, assembly” allowing the Windsor container to find your service implementations.

Next you need to add the relevant WCF configuration, it’s quite lengthy if you’re explicit, but descriptive.

<system.serviceModel>
   <bindings>
     <netTcpBinding>
       <binding name=”IExampleContractBinding”
        transferMode=”Buffered”
        transactionProtocol=”OleTransactions”
        hostNameComparisonMode=”StrongWildcard”
        closeTimeout=”00:01:00″
        openTimeout=”00:01:00″
        receiveTimeout=”00:10:00″
        sendTimeout=”00:10:00″
        transactionFlow=”false”
        maxBufferPoolSize=”50000000″
        maxBufferSize=”268435455″
        maxReceivedMessageSize=”268435455″
        maxConnections=”10000″
                >
         <readerQuotas
           maxDepth=”50000000″
           maxStringContentLength=”50000000″
           maxArrayLength=”50000000″
           maxBytesPerRead=”50000000″
           maxNameTableCharCount=”50000000″
         />
         <reliableSession ordered=”false”
           inactivityTimeout=”00:10:00″
           enabled=”false”
         />
         <security mode=”None”>
           <transport clientCredentialType=”Windows” />
           <message clientCredentialType=”Windows”/>
         </security>
       </binding>

     </netTcpBinding>

   </bindings>

   <behaviors>
     <serviceBehaviors>

       <behavior name=”IExampleContractBehaviour”>
         <serviceMetadata httpGetEnabled=”true” />
         <dataContractSerializer maxItemsInObjectGraph=”100000″/>
         <serviceThrottling maxConcurrentCalls=”100″ maxConcurrentSessions=”100″ />
       </behavior>

     </serviceBehaviors>
   </behaviors>

   <services>
     <service name=”DEJW.ServiceImplementations.ExampleContractImpl” behaviorConfiguration=”IExampleContractBehaviour”>

       <endpoint name=”IExampleContractEndpoint”
                 address=”query”
                 binding=”netTcpBinding”
                 bindingConfiguration=”IExampleContractBinding”
                 contract=”DEJW.ServiceContracts.IExampleContract” />

       <endpoint name=”IExampleContractMetaData”
                 address=”mex”
                 binding=”mexHttpBinding”
                 contract=”IMetadataExchange” />

       <host>
         <baseAddresses>
           <add baseAddress=”net.tcp://localhost:8000/DistributedServer” />
           <add baseAddress=”http://localhost:8001/DistributedServer” />
         </baseAddresses>
       </host>
     </service>

     <service name=”DEJW.ServiceImplementations.ExampleContractTwoImpl” behaviorConfiguration=”IExampleContractBehaviour”>

       <endpoint name=”IExampleContractTwoEndpoint”
                 address=”query”
                 binding=”netTcpBinding”
                 bindingConfiguration=”IExampleContractBinding”
                 contract=”DEJW.ServiceContracts.IExampleContractTwo” />

       <endpoint name=”IExampleContractTwoMetaData”
                 address=”mex”
                 binding=”mexHttpBinding”
                 contract=”IMetadataExchange” />

       <host>
         <baseAddresses>
           <add baseAddress=”net.tcp://localhost:8002/DistributedServer” />
           <add baseAddress=”http://localhost:8003/DistributedServer” />
         </baseAddresses>
       </host>
     </service>
   </services>
</system.serviceModel>

Obviously your mileage may vary with the above configuration (a lot of those values are values I’ve used in my day job for development purposes, but you’ll want to tighten down lots of those values and, I suspect, enable security for any production system).

Control Application

The control application that goes with this code is practically nonexistent (one of the stated goals) just stick the aforementioned usage example in the main method, followed by some kind of message and a ReadLine() to stop the application exiting.  Something akin to:

_hostManager = new HostManager();
_hostManager.AddServiceContracts(PlugableServiceFactory.RetrieveCollectionOfPlugableServices());
_hostManager.StartListening();

Console.WriteLine(”Press any key to exit”);
Console.ReadLine();

For the windows service implementation create a static instance of HostManager and override protected override void OnStart(string[] args), in this method call the StartListening() method on HostManager, and override OnStop to call the StopListening() method for a clean shutdown.

Maintainability

The key benefit to this approach to service hosting is how trivial it makes expanding your services.  In order to add extra functionality to an existing service you need to modify the service contract and service implementation, recompile those two projects and let the HostManager do the rest.  If you wish to host an entirely new service, create a new service contract and implementation, and remember to add a configuration section to app.config, and again, let HostManager take care of the details.

 

Source code

The source code provided here is NOT a compiling project.  Instead I’ve provided the CommunicationManager project (if you’ve read the above details you’ll realise that’s all you really need), the example ServiceContracts and example ServiceImplementations, alongside the example unit test and an example App.config.

If you wish to use this code, remember you’ll need a copy of the Windsor components, you’ll need NUnit if you want to run the unit test and you’ll need to write your own console / service wrapper.

Some of the code in here was inspired by writing a more specific service for my employer that made me wonder if I could abstract the service host portion of the code into a more general purpose application.  Apparently it was possible!  I’ve not reused any code however I’d imagine the similarities are striking, so whilst not “production tested”, the methods and techniques used should be relatively bug free.  No warranty etc etc, but I hope somebody finds this useful.  It’s definitely the approach I intend to take to authoring services from this point forwards.

 Download GenericWCFServer.zip

Now Playing: Zimmers Hole - When You Were Shouting At The Devil… We Were In League With Satan