Archive for the ‘geek’ Category

Embrace, Extend, Extinguish: Integration with Uncooperative Systems

Saturday, July 12th, 2008

Cornered By Technology

It’s not uncommon in enterprise software development to be tasked with integrating with a third party platform that just won’t play nicely however hard you try. These scenarios often creep up on you at the most unexpected time, be it as a requirement, or a partnership with an uncooperative or unskilled vendor or technical partner. Even worse, it can often become clear that the relationship between your platform and a third party platform is effectively untenable after you’ve invested significant development effort to get “most of the way” there.

The Need for Application and Data Separation

The really bad news is that this isn’t an uncommon scenario, and there are countless businesses operating whilst being held to ransom by systems that they paid for. Unfortunately, these systems cannot be abandoned, normally because the system holds some crucial operational data that the company would cease to function without. Antiquated CRM solutions, Billing platforms and databases are a few of the most common places these issues arise. The fact that you’ve been effectively backed into a corner by a technology partner isn’t the root of the problem however.

These scenarios normally spawn from a historic or bad choice in application design either on your own part or on the part of the offending partner as a side effect of intertwining corporate data and applications into a tightly coupled relationship. You shouldn’t offer the keys to your business to any single piece of software, especially a piece of software operated by a third party, and it’s of the highest importance that you have a clear exit strategy if you choose to enter such an abusive relationship.

Anyone that works with real software on a day to day basis well knows that a full separation of software and the data on which it operates isn’t entirely practical. In reality, you are going to end up with applications controlling certain portions of your data in proprietary formats, but with due diligence and a mind for separation of concerns when choosing available solutions, business crippling crisis should be easy to avoid.

When choosing platforms and service partners, don’t skim over the details of data storage, try and ensure any application that you’re trusting with your business data is storing it in a way that you can migrate that data elsewhere if you so desire.

All People Perform To the Best of Their Abilities When Available Time and Constraints Are Accounted For

It’s very easy to become adversarial when faced with a business crippling technology partner or application and it’s of the upmost importance that you keep your ego and temper in check when dealing with an especially uncooperative partner. This sounds like an obvious piece of advice when dealing with people but it’s just as appropriate a guideline when dealing with software.

Don’t do or say anything you’ll regret, don’t antagonise your opposition (and if you’re unlucky, an uncooperative service partner will certainly become an opponent), and certainly don’t make any knee-jerk decisions regarding your own codebase. It’s important to remember that whilst the system you’re attempting to integrate with may well appear intentionally antagonising or impossible. It’s likely that the functionality of the system was not achievable in any other way, and you genuinely are working with the best product that is available. Concentrate on productive measures, not the conflict and stress of a business threatening problem.

It’s Not You, It’s Me

It should be quite evident that there’s only one solution to this particular problem; technical divorce.
The goals of a project to end an abusive software relationship are reasonably clear cut and simple:

  1. Don’t negatively impact business operation without good reason.
  2. Achieve data and application logic separation.
  3. Escape with minimal impact on other integrated systems.
  4. Take preventative measures; don’t get hurt again.

Your number one goal is to not disrupt day to day business during this period of technical therapy. You need to continue working with your technology partner on a daily basis in order to operate and it’s important that you don’t anger your partners or hinder the operation of the soon to be replaced system with disruptive development. Following good software development practices in general should ensure you avoid technical issues of these kinds.

Your second goal is to separate your mission critical data from the dying system. Data ownership is a huge task and not something that can be summed up in a few paragraphs. You may need business analysts to investigate who owns the data in your business and where it should reside. As a good guideline, it’s worth considering that as a business you should own all of your business data with specific applications fed on the data they require to operate. Results should be imported back into a master database or data-store. It’s not a silver bullet or a solution for everyone, but if you approach the problem of data ownership from this perspective then you’re at least thinking along the right track where your applications are secondary to your data needs. An order tracking system should only be concerned with order items and names, a billing system should only be concerned with financial data and billing, try and ensure you don’t get lost in a spaghetti mess of duplicated data.

Your third and most difficult goal is to make this process transparent to the end user by reducing the impact of the change on your other systems. I’ll spoil the fun now by telling you that this is probably impossible and that the user will see a difference. The key is ensuring that difference is only ever iterative improvement to existing business processes and never prohibitive to productive work.

The fourth goal is preventative and hard to define. Seeing as you’re going though this painful technical divorce, ensure that the amount of thought and work that goes in to this project is sufficient to prevent this scenario reoccurring. Employ good business analysts to help you design the project, investigate data ownership and data warehousing, invest in technologies that adhere to open standards and allow for data portability. Build your replacement system in such a way that when you want to replace it with the next wave of technology, that your own developers won’t face the challenges you’re facing now.

Designing a Solution

In order to escape from this heavily relied upon piece of software we’d do well to learn a few tricks from the people who have participated in Software Modernisation over the years.

The Wikipedia entry for software modernisation (http://en.wikipedia.org/wiki/Software_modernization) reads;

“Software Modernization is the process of understanding and evolving existing software assets.

There is a vast amount of highly functional, operational software, representing enormous commercial value deployed in organizations around the globe. To be precise, existing systems are defined as any production-enabled software, regardless of the platform it runs on, language it’s written in, or length of time it has been in production.

These entrenched software systems often resist evolution because their strategic value and ability to adapt has diminished through factors not exclusively related to its functionality. Common examples of such factors are a system’s inability to be understood or maintained cost-effectively, inability to interoperate or dependence on undesired technologies or architectures”

The goals of software modernisation are functionally similar to the goals of replacing an uncooperative system, albeit with a different motivation for the system replacement. This “modernisation” is happening due to the need to maintain defective but business critical operations in the short term rather than retaining currently good functionality in the long term.

Software modernisation is a whole topic in and of itself, but at its core there are two common methods of modernising software; black box modernisation and white box modernisation. These terms retain their standard computer science meanings.

Both modernisation practices require the encapsulation of the legacy system in modern code, creating a fresh set of APIs in a modern language, which in turn calls an API or function of the legacy system.

Black box modernisation involves calling only the publicly facing APIs of the legacy system where as white box modernisation involves a degree of knowledge of the underlying platform and its operations. It’s exceptionally common for extensive reverse engineering of a platform to take place in white box modernisation whilst black box modernisation is more or less a thin wrapping layer.

We’re going to take the idea of system encapsulation from software modernisation and treat our uncooperative system as though it were a legacy system and develop an API to encapsulate the systems functionality.

Function Not Form

During the “aggressive replacement” of the uncooperative system, modern development methodologies will get you a long way. You should keep a keen focus on loose coupling of the interface you create to describe the business needs and the underlying wrapping code of the system beneath it.

When designing your replacement API, you should endeavour to describe the business needs rather than mapping new API calls to the uncooperative system in a one to one fashion. You should take great care to describe function rather than form, decoupling the core business needs from the implementation underneath.

Good API design isn’t something you wake up with the innate ability to do, and thoroughly describing the business requirements of the uncooperative system in your new API will likely take several iterations. This isn’t a problem however, as it’s recommend that you iterate through a process of this scope rather than attempt some big bang replacement of the uncooperative system to avoid great risk and inconvenience to the business.

Your API should creep in to existence, method by method. Existing applications should be updated to use the new API methods as their developed to allow for an iterative migration to the new wrapping code.

Embrace, extend, extinguish

Once you’ve designed the API you wish to use to replace your uncooperative system, you actually have to produce code that maps between the two.

This is no small task and will probably be the majority of the work required by the project. This code is very implementation specific. You may be able to just codify your new APIs in to a few API calls of the uncooperative system itself, conversely you may have to deconstruct the behaviour of the system and replicate it in entirely fresh code. Either way, it’s exceptionally important that at this stage you keep your implementation separate from your API and service layer.

Thus far we’ve embraced and accepted our uncooperative system, we’ve extended a hand towards it in the form of a neatly designed API, and the final step of your project will revolve around replacing the system entirely.

Once your API is fully featured, and all the dependant systems in your business are referencing it for any communication they need to perform you can begin seeking a replacement system.

Choose wisely, at this point you’ll likely be more than aware of the pains involved in another costly migration! Take your time, there’s no hurry, developing your own solution is even an option.

Once you’ve chosen the replacement, you need to write some code again, this time to translate calls from your new API across to your replacement system. Because you did remember to keep your API decoupled from the implementation, right?

At this point you’ve succeeded in using an iterative approach to software design to fully replace a system that may have previously seemed inseparable from the business. The ROI of a project of this nature is hard to quantify, but I thoroughly believe that if you feel that you need to embark on a project of this nature, its completion will surely strengthen one of the most brittle parts of your operational business.

Congratulations! You made it out alive.

Footnote: Avoid the same thing happening to you

This is honestly a plea to anyone that’s ever going to write a system they expect other developers to communicate with. Practice designing APIs. Write them well. Document them well. Keep them up to date. Support them. Define concise operations. Be good. If everyone is “good” then hopefully fewer people will have to suffer difficult integration exercises.

The Vote Of No Confidence In The Entity Framework

Wednesday, June 25th, 2008

It appears as though the Microsoft M.V.P’s that were called upon to advise on the technicalities of the forthcoming Entity Framework hit a little bit of a roadblock.

When I say “a little bit”, it seems as though Microsoft just point blank disregarded their warnings and recommendations in regard to creating OR mappers. It’s probably the first time I’ve seen this kind of scenario end with the technical advisors posting a warning and a general vote of no confidence.

I’d be lying if I didn’t say I felt a little disappointed that after making steps in the right direction and asking domain specialists for advice, that Microsoft entirely disregarded the advice of the specialists they consulted resulting into what seems like an unusable shipping product.

I’ve not attempted to use the entity framework in and form, but the technical criticisms in the vote of no confidence are quite explicit, and as a developer who makes extensive use of OR/M, if those criticisms are accurate (which is very likely) I’d certainly treat the entity framework with the same unfortunate disregard.

At least nHibernate isn’t broken!

C# Developers Toolbelt

Sunday, June 8th, 2008

There’s a very good argument for saying that the thing that makes or breaks a new programming language is actually the tools the work with and around it, rather than language features themselves.  If you ask the average programmer to guess the percentage of language features of their language of preference that they used on a daily basis, or even ever, I suspect many of them would respond somewhere in the 25-30% range. 

Programming languages these days are big.  By that I mean, programming frameworks these days are big.  Most people tend to not just use the language natively, but the selection of a preferred platform tends to be based on the features of the dominant framework available for that language.  As a simple statement this is neither here nor there, but it illustrates the point that the development environment, for a large proportion of its users, makes a language.  I’d argue that Visual Studio made Visual Basic popular, and that without it, it would probably haven’t stood a chance against Turbo Pascal and Delphi, even with all the clout of Microsoft.  So we rely on tools, and in honour of tools, here are a list of tools I find invaluable whilst developing in .NET.

JetBrains ReSharper

This is the king of all visual studio plug-ins.  Imagine it as a kind of, interactive FX cop while you work.  It offers background compilation, refactorings, stream lines existing visual studio functionality and basically makes you code better.  It teaches you things you didn’t know about the language and helps you improve your code quality proactively rather than retrospectively.  The biggest programming crutch known to man, and a descendant of the IntelliJ IDE for Java.  JetBrains have trials available and if you drop my name in you can get an improved trial period and a bit of a discount on purchases.  If I could take just one tool home, it’d be this.

Lutz Roeder’s Reflector

Ever thought that there was a bug in someone else’s compiled assembly?  Fancy a crawl around the internals of the .NET framework?  This is the tool for you.  Reflector translates the IL of a compiled assembly back in to C# and lets you poke around inside.  It’s very much read only, but if you ever think there’s a bug in something you’re not supposed to touch, you can prove it and code around it with the help of this excellent tool.

System Internals / Microsoft Debug View

I’ve written about the usefulness of this little application in the past.  Debug View lets you view the Windows Debug output stream in real time.  That’d be anything written using System.Diagnostics.Debug.WriteLine or the more traditional C / C++ equivalents.  Allows you to monitor an application built in a debug state in real time.  Perfect for debugging Windows services or other troublesome applications that you need to monitor whilst running during development.

Visual Studio Remote Debugger

If you have Visual Studio you actually already have this (the link above is to setup information).  It’s hidden away in C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\Remote Debugger (replace the visual studio version as applicable) and it allows you to attach an instance of Visual Studio to an application running on another machine.  Again invaluable if you’re writing distributed services and deploying to test servers, this application allows you to run your service or application on another machine, then connect to it using the visual studio debugger and break and step through your code as though it were on your local machine.  Great for when you deploy something to an integration test server, it fails, and you just can’t work out why without digging through the code in real time.

MbUnit and Rhino Mocks

Two for one, an xUnit derived unit testing framework, and Ayende’s mocking framework.  Unit test with confidence and unit test often.

ANTS Profiler

ANTS profiles your .NET applications at a level I’ve not seen in any competing products, giving you a line by line, method my method breakdown of execution time and code bottlenecks along with all the stats you could ever want to generate on a piece of code.  You really can use this to find horrible hidden performance issues in your code and fix them.

Honourable Mentions

Notepad++

Everyone has their own favourite notepad replacement utility.  This is mine.  I used Context for years but this is just better in every way..

Pro C# and the .NET 3.5 Platform

The only “giant programming bible” I’ve ever been able to read like a book.  Grab an E-book so it’s searchable and you’ll probably get more information than you could Google for.

These are just my personal preferences, and applications that I use on a daily basis.  Give a few of them a try and you’ll see your productivity increase and hopefully, your code improve.

RunAsRadio - Scott Kveton Shares His OpenID!

Friday, March 28th, 2008

http://www.intellectualhedonism.com/2008/02/13/RunAsRadio44ScottKvetonSharesHisOpenID.aspx
Richard and Greg talk to Scott Kveton about OpenID. OpenID is a single sign-on solution that could very well make the classic username and password obsolete. This is a fast half hour - you’ll find yourself wanting to listen again!

Coincidently so soon after writing my last post, something I’ve been listening to whilst coding today, really interesting half hour show on openId and unification of functionality.

I’ve spent a little time in the past evening writing a .NET/ASP OpenId provider based on some open source code build on top of the JanRain librarys. Their sample was simple and forms authentication based, and I’ve been expanding it to work in a multiuser environment using flat files to store XML user identities behind the scenes. When it’s done I’ll submit the changes back to the source / open it, but it’s more of a fork of the orignial project (which itself appears to be based on just about everything ever).

Fractured Online Identities

Wednesday, March 26th, 2008

This post was originally going to be a response to my friend Stevens post on the same topic “Isn’t it odd..” (Steven Westwell on social networking) so I’d read that first in case I’ve missed something in the overwrite to a post here.  His response turned in to an essay, and so has my own.

I’m eternally divided on the topic of social and collaborative software and the workplace, and even in leisure time.

The experience people currently have with social networking is really zeitgeist and faddish behaviour, people check their facebook over personal email at the moment because it’s new and exciting, it’s something they’ve not had previously, though month after month since about November 2007 facebook and to an even greater extent myspace have seen a steady reduction in both traffic and user activity.  I’m convinced that today’s social networking, from the walled garden of the MSN network, sorry, Facebook ( ;) ), to the focusless indirection of twitter aren’t actually setting the mould for community communication, they’re a “web two point oh-ey” version of phpBB and usenet more than anything.

I’d actually say spam currently poses a greater threat to traditional email than social networking could possibly manage.

That said, it’s correct to identify user driven communities as the direction things are and should be moving, but I see the success in this is directly linked to the maturity of unified online identities, rather than scattered ecosystems.  It’ll take a killer app in the form of Windows Live (even based on the success of XboxLive), or OpenId (I prey for the latter but I’m reasonably certain it’ll be the former) to act as the overall identity broker before people start to establish solid content driven identities on the Internet.

The biggest barrier obstructing the path of social networking becoming as ubiquitous as email is the walled gardens it builds around itself.

The Mecca of the “web 2.0″ concept really is distributed social networking, driven by network events to publish stories, events, “friend requests” and other unspecified interactions (RRS and Atom feeds serving as the first implementation of this “half-push” technology).  A user should control their own identity, have the right to elect the authority who controls their identity (see OpenId), or control their own.  Until the social networking sites stop trying to wall in their users (like AOL, ICQ, MSN, Yahoo, local BBS’, The Microsoft Network, Facebook, Myspace, etc before them) we’ll spend a few years in the wilderness of disparate online identities and large communities achieving moderate success before vanishing.

Social networking platforms need to concentrate on adding value to the user experience, rather than trying to consistently reinvent the wheel.  If they were software project propositions this kind of behaviour alone would doom them to failure.  Innovation should be celebrated, and developers certainly shouldn’t have to produce “yet another user management system” with all the features of their direct predecessors, just a little better, or a little more shiny.  The bread and butter of social interaction should be standardised protocols for communication between unrelated innovative “value added” sites.

The kind of interactions suggested, distributed file storage, notifications and calendars exist in products like SharePoint, and mediawiki, iCal and traditional email, but until they’re tied together correctly they’re doomed to be noise.  I really believe that until collaboration technology matures to be platform independent that it’ll struggle to permanently compete and shape networking on a broader scale.  I work entirely in the Microsoft ecosystem and I still feel it’s very important that Microsoft should not tell you who you are online, nor should Facebook, Blogger nor Apple.

Interestingly there’s a different set of challenges facing the adoption of technologies like instant messaging in the workplace, and they’re all entirely human.  Staff training and trust with communication mediums that can be painted as time wasting will always struggle to garner acceptance.  That said, I’ve used instant messaging for years in the workplace, but I’d imagine most technical companies will be ahead of the curve in this respect.  It’s interesting if you look at studies of how wasteful people make checking email on a daily basis, after you account for disruption in flow and response times.  It’s actually (at least in my experience) far more efficient to have email delivered on a pull basis, in intervals measured in hours.  People get more done when they only check their mail four times a day.

I’m really really excited about the future of social networking and its place as the main content driver of “web 3.0″, but I like to imagine it more in the vein of the Ainsible networks of Orson Scott Cards “Enders Game” than the cheap message board hacks of myspace and their application ecosystem.  I’m striving to unify my online identity and I’d implore anyone else to do the same.

Development Tricks: Debug View

Friday, February 22nd, 2008

I’m often surprised that people haven’t come across this wonderful ex-System Internals (now Microsoft) tool.

Debug View

Debug view allows you to see debug messages written by any application currently running compiled with debug symbols.  To .NET developers, those would be the messages you can write out with System.Diagnostics.Debug.WriteLine(); 

Why would you want to do that?  Well… if you grace your application with a healthy dose of debug messages, you can monitor the performance of applications whilst they’re deployed or in a production environment without having to break out the debugger.  Often a nice quick way to see what a system service is up to, or why your web application appears to be misbehaving.

I currently make use of a combination of this and some IOC magic on a daily basis to monitor in-development services as part of a distributed system (hint: create a wrapper class for writing output messages, then implement it in various ways, Console.WriteLine, Debug.Writeline, etc, even a null implementation to save performance in production environments…) and genuinely don’t know what I’d do without it.

And hell, if you’re really bored it’ll let you know which Windows components are running with debug symbols compiled in (ActiveSync, I’m looking at you…).

Now Playing: Zimmers Hole - Flight Of The Knight Bat

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

Thursday, 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

Duke Nukem Forever Trailer Pt.2

Thursday, December 20th, 2007

http://www.youtube.com/watch?v=ZUN7mHUtzno

Well, it did actually happen, I’ll give them that.
Looks… like a teaser trailer.

Zelda DS "The Phantom Hourglass".

Friday, March 9th, 2007

Kotaku just posted an epic looking trailer for the forthcoming Zelda DS game. Looks like an epic mixture of old and new school Zelda, honestly can’t wait.

http://kotaku.com/gaming/clips/clip-phantom-hourgl…

I was one of the 0.0000% of the world that actually loved the Windwakers art directing so to be honest, extra points for keeping it around.

Oh and I noticed yesterday that apparently Burnout 5 is out on the first of next month, another game I’m really looking forward to despite knowing nothing about. Burnout 3 was fantastic, Burnout 4 was Burnout 3.5, apparently they’re opening up the world in the new one, removing menus and making it a little more persistent. Dangerous to mess with something that works so brilliantly, but I’m tempted to throw a preorder in there anyway. I can’t seem to find any preview information on the game though, which makes me somewhat wary.

Sony PR.

Wednesday, March 7th, 2007

http://www.engadget.com/2007/03/07/sonys-playstati…

Sony announces “Playstation Home”.

Oh sony oh sony oh sony. No more than a week after you try and threaten the largest gaming blog on the internet (http://kotaku.com/gaming/top/sony-blackballs-kotak…), followed up by a swift backpeddle following public outrage (http://kotaku.com/gaming/sony/sony-and-kotaku-make…), do you go and announce the very service you were trying to keep under wraps by via threat.

Not only did they confirm the rumour last week with some classic corporate mismanagement, but to take such a swift stance on something so imminent really does escape me.

So let me get this straight. An expensive, late, crippled games console, an unlimited number of pr and technical bundles, and yet you still desperately hope that previous market dominance will let you coast through to victory in a technology battle?

Begs belief.

All contents ©David Whitney 1998-2008 unless otherwise stated.