Tuesday, June 30, 2009

IronPython in Action

image Writing a book about IronPython presents a dilemma, do you write a book introducing Python to .NET developers, or do you write a book introducing .NET to Python developers? Striking the right balance between the two is always going to be difficult, but Michael Foord and Christian Muirhead have made a very compelling attempt. Of course I can’t speak for the Python hacker coming to the world of .NET for the first time, but for a .NET guy like me, the book is an excellent introduction to Python and how IronPython works with the rest of the .NET ecosystem.

It’s a very well written and crafted book, with an easy to read conversational style. I find many programming books quite hard work, but this one was a pleasure.

The compromise for me was a rather too high level introduction to Python itself, I would have preferred a deeper introduction to the details of Python and its standard libraries. But then I guess I could always go and buy a Python book, or check out the prodigious online resources for a more in-depth view. I’m not particularly interested in Winforms programming, so I didn’t really get much out of those parts of the book, but I guess the detail is understandable when you know that the authors day job is programming a large winforms system, Resolver One. Chapter 8 on metaprogramming and protocols was very interesting for a dynamic newbe like me, and chapter 15, on embedding the IronPython engine, also sparked off quite a few ideas.

I disagree with Craig Murphy’s comment on the back cover, “… and if you are new to programming, it’s for you too.” Michael and Christian go too deep too fast for a complete beginner. You would really need to have some background in either .NET or Python to get the most out of this book.

So am I excited about IronPython? A bit. I think I need to actually try some serious programming with it. For me its two obvious applications are as an embedded scripting language and for those tasks that don’t justify a fully compiled .NET application, such as automated deployments. I’m sure that you could be very successful building large applications with it, as indeed the authors have, but I don’t feel immediately compelled to drop C#.

I’m certainly not as excited about IronPython and the DLR as I am about functional languages such as F#. Functional programming really is a new paradigm. If you told me we would all be writing our applications with dynamic languages in ten years time, I’d be sceptical. But with functional languages, I’d be inclined to agree. Maybe we will see the emergence of a more polyglot programming ecosystem? In that world there’s certainly a place for IronPython.

Thursday, June 11, 2009

TFS Build: _PublishedWebsites for exe and dll projects

We’re using TFS on my current project. Yes, yes, I know.

It’s generally good practice to collect all the code under your team’s control in a single uber-solution as described in this Patterns and Practices PDF, Team Development with TFS Guide. If you then configure the TFS build server to build this solution, it’s default behaviour is to place the build output into a single folder, ‘Release’.

Any web application projects in your solution will also be output to a folder called _PublishedWebsites\<name of project>. This is very nice because it means that you can simply robocopy deploy the web application.

Unfortunately there’s no similar default behaviour for other project types such as WinForms, console or library. It would be very nice if we could have a _PublishedApplications\<name of project> sub folder with the output of any selected project(s). Fortunately it’s not that hard to do.

The way _PublishedWebsites works is pretty simple. If you look at the project file of your web application you’ll notice an import near the bottom:

<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />

On my machine the MSBuildExtensionsPath property evaluates to C:\Program Files\MSBuild, if we open the Microsoft.WebApplication.targets file we can see that it’s a pretty simple MSBuild file that recognises when the build is not a desktop build, i.e. it’s a TFS build, and copies the output to:

$(OutDir)_PublishedWebsites\$(MSBuildProjectName)

I simply copied the Micrsoft.WebApplication.targets file, put it under source control with a relative path from my project files and changed _PublishedWebsites to _PublishedApplications and renamed the file CI.exe.targets. For each project that I want to output to _PublishedApplications, I simply added this import at the bottom of the project file:

<Import Project="<your relative path>\CI.exe.targets" />

You can edit CI.exe.targets (or whatever you want to call it) to do your bidding. In my case, the only change so far is to add a couple of lines to copy the App.config file:

<Copy SourceFiles="$(OutDir)$(TargetFileName).config" DestinationFolder="$(WebProjectOutputDir)\bin" SkipUnchangedFiles="true" />

There’s a lot of stuff in Microsoft.WebApplication.targets that’s only relevant to web applications and can be stripped out for other project types, but I’ll leave that as an exercise for the reader.

There was also a discussion on StackOverflow, with some nice alternative suggestions of how you might want to do this. It’s worth checking out.

Friday, May 29, 2009

What I look for in a Code Review

I recently put this bullet point list together for the team I’m currently working with.

Naming Conventions

General Principles

  • The core imperative is to organise complexity.
  • Clarity and readability is central. “Intention Revealing”
  • Do not prematurely optimise for performance.
  • Do not repeat yourself. Never copy-and-paste code.
  • Decouple.
  • Always try to leave the code you work on in a better state than before you started (the ‘boy scout’ principle)

Keep the source clean

  • Always delete unused code. Including variables and using statements
  • Don’t comment out code, delete it. We have source control to manage change.

Naming things

  • The name should accurately describe what the thing does.
  • Do not use shortenings, only use well understood abbreviations.
  • If the name looks awkward, the code is probably awkward.

Namespaces

  • Namespaces should match the project name + path inside the project. This is what VS will give you by default.
  • Classes that together provide similar functions should be grouped in a single namespace.
  • Avoid namespace dependency cycles.

Variables

  • Use constants where possible. Avoid magic strings.
  • Use readonly where possible
  • Avoid many temporary variables.
  • Never use a single variable for two different puposes.
  • Keep scope as narrow as possible. (declaration close to use)

Methods

  • The name should accurately describe what the method does.
  • It should only do one thing.
  • It should be small (more than 10 lines of code is questionable).
  • The number of parameters should be small.
  • Public methods should validate all parameters.
  • Assert expectations and throw an appropriate error if invalid.
  • Avoid deep nesting of loops and conditionals. (Cyclomatic complexity).

Classes

  • The name should accurately describe what the class does.
  • Classes typically represent data or services, be clear which your class is.
  • Design your object oriented schema deliberately.
  • A class should be small.
  • A class should have one responsibility only.
  • A class should have a clear contract.
  • A class should be decoupled from its dependencies.
  • Favour composition over inheritance.
  • Avoid static classes and methods.
  • Make the class immutable if possible.

Interfaces

  • Rely on interfaces rather than concrete classes wherever possible.
  • An interface is a contract for interaction.
  • An interface should have a single purpose (ISP)

Tests

  • All code should have unit tests if possible.
  • Test code should have the same quality as production code.
  • Write code test-first wherever possible.

Error Handling

  • Only wrap code with a try..catch statement if you are expecting it to throw a specific exception.
  • Unexpected errors should only be handled at process boundaries.
  • Never ‘bury’ exceptions.

Mike Ormond interviews me about the MVC Framework

This week Mike Ormond made the trip down to Brighton to join me for lunch and talk about ASP.NET MVC. He’s put together a couple of videos based on our chat. The backdrop is Brighton’s most famous landmark, The Pavillion.

 

Saturday, May 09, 2009

Multi-tenanted services with the Windsor WCF Facility

This is the sixth in a series of posts featuring the WCF Facility:

Windsor WCF Integration
WCF / Windsor Integration: Using the perWebRequest lifestyle
WCF / Windsor Integration: Adding Behaviours
Atom feeds with the Windsor WCF Facility
Windsor WCF Facility: MessageAction and MessageEnvelopeAction

Download the code for this post here:
http://static.mikehadlow.com/Suteki.Blog.zip

A while back I started writing a series of posts on Multi-tenancy. This is the idea that a single instance of your application can host multiple clients with varying requirements. An IoC container such as Windsor is an excellent enabling technology for doing this. It allows you to compose varying object graphs at runtime depending on some context.

For example, I recently had a client with an integration requirement to a legacy system that they had developed in house. The legacy system was deployed with one instance in London and another in New York. The US and UK requirements differed slightly and so two versions of the application had been developed. I wanted a single service that could handle the needs for both legacy systems. Since they were 90% similar it made sense to simply swap in different components for where they differed.

In this post I want to show how to host a single instance of a service that can compose different components depending on the host name.

Say we have two domain names: red.shop and blue.shop. We can configure IIS with the two host headers (bindings):

iis_multitenanted

The first thing to notice when you do this with a standard WCF setup, is that you get an error:

multi_hostheader_error

“This collection already contains an address with scheme http.  There can be at most one address per scheme in this collection.” That’s right, WCF doesn’t play nicely with multiple host headers/bindings. This is a major complaint and Microsoft have gone some way to resolving it by providing a mechanism where you can specify a single address that service will listen for. Unfortunately that doesn’t help us. We want to listen for any request arriving at the service and then use its hostname to compose our components.

There is a workaround. The addresses for an endpoint are passed from IIS to WCF via the ServiceHostFactory. If you intercept this and pass an empty list of addresses, WCF falls back to using configured endpoint addresses.

All we need to do is write a custom ServiceHostFactory that grabs the addresses and then configures our service component with multiple endpoints. The WCF Facility already provides a custom ServiceHostFactory, the WindsorServiceHostFactory, so we can simply specialise that:

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Diagnostics;
   4: using System.ServiceModel;
   5: using Castle.Facilities.WcfIntegration;
   6: using Castle.MicroKernel;
   7: using Suteki.Blog.Multitenanted.IoC;
   8:  
   9: namespace Suteki.Blog.Multitenanted.Wcf
  10: {
  11:     public class MultitenantedServiceHostFactory : WindsorServiceHostFactory<DefaultServiceModel>
  12:     {
  13:         public MultitenantedServiceHostFactory(){ }
  14:  
  15:         public MultitenantedServiceHostFactory(IKernel kernel)
  16:             : base(kernel)
  17:         { }
  18:  
  19:         public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
  20:         {
  21:             AddEndpoints(constructorString, baseAddresses);
  22:  
  23:             // passing no baseAddresses forces WCF to use the endpoint address
  24:             return base.CreateServiceHost(constructorString, new Uri[0]);
  25:         }
  26:  
  27:         protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
  28:         {
  29:             AddEndpoints(serviceType, baseAddresses);
  30:             return base.CreateServiceHost(serviceType, new Uri[0]);
  31:         }
  32:  
  33:         private static void AddEndpoints(Type serviceType, Uri[] baseAddresses)
  34:         {
  35:             var handler = ContainerBuilder.GlobalKernel.GetHandler(serviceType);
  36:             AddEnpoints(baseAddresses, handler);
  37:         }
  38:  
  39:         private static void AddEndpoints(string constructorString, Uri[] baseAddresses)
  40:         {
  41:             var handler = ContainerBuilder.GlobalKernel.GetHandler(constructorString);
  42:             AddEnpoints(baseAddresses, handler);
  43:         }
  44:  
  45:         private static void AddEnpoints(Uri[] baseAddresses, IHandler handler)
  46:         {
  47:             var endpoints = new List<IWcfEndpoint>();
  48:  
  49:             // create an endpoint for each base address
  50:             foreach (var uri in baseAddresses)
  51:             {
  52:                 endpoints.Add(WcfEndpoint.BoundTo(new BasicHttpBinding()).At(uri.ToString()));
  53:             }
  54:  
  55:             // add the endpoints to the service
  56:             handler.ComponentModel.CustomDependencies.Add(
  57:                 Guid.NewGuid().ToString(), 
  58:                 new DefaultServiceModel().Hosted().AddEndpoints(endpoints.ToArray()));
  59:         }
  60:     }
  61: }

All the action happens in the final AddEndpoints method. We use the WCF Facility’s fluent configuration to create an endpoint for each address that IIS gives us (effectively an address for each host header) and then add the endpoints to the Kernel’s component model for the service that is being hosted.

Note that I’m simply adding a custom dependency to the component model. The WCF Facility automatically searches the hosted component’s custom dependencies for service models. The DefaultServiceModel simply specifies the WCF BasicHttpBinding.

Note also that I have to use a service locator (ContainerBuilder.GlobalKernel) to get a reference to the Kernel because the WindsorServiceHostFactory’s kernel field is private rather than protected. It would be nice if this could be changed…. Craig?

Next we need to alter our svc file to point to our custom ServiceHostFactory:

<%@ ServiceHost Service="blogService" Factory="Suteki.Blog.Multitenanted.Wcf.MultitenantedServiceHostFactory, Suteki.Blog.Multitenanted"  %>

Now we can happily call the service from both http://red.shop/BlogService.svc and http://blue.shop/BlogService.svc.

If you simply want your service to work with multiple bindings this is all you have to do. However, as I described above, we might also want to compose our service based on the hostname.

For that we need to write an IHandlerSelector that can choose components based on the current host name. I’ve written about how to this in a web application here. Please read that first if you haven’t encountered IHandlerSelector before.  We use a similar approach, but this time we are going to use the very handy Windsor NamingPartsSubSystem to give our components a hostname parameter that we use to match on.

   1: using System;
   2: using System.Linq;
   3: using System.Diagnostics;
   4: using System.ServiceModel;
   5: using Castle.MicroKernel;
   6:  
   7: namespace Suteki.Blog.Multitenanted.IoC
   8: {
   9:     public class HostBasedComponentSelector : IHandlerSelector
  10:     {
  11:         private readonly IKernel kernel;
  12:  
  13:         public HostBasedComponentSelector(IKernel kernel)
  14:         {
  15:             this.kernel = kernel;
  16:         }
  17:  
  18:         public bool HasOpinionAbout(string key, Type service)
  19:         {
  20:             if (OperationContext.Current == null) return false;
  21:             
  22:             var componentKey = GetComponentKeyWithHostnameParameter(key, service);
  23:             return kernel.HasComponent(componentKey);
  24:         }
  25:  
  26:         private static string GetComponentKeyWithHostnameParameter(string key, Type service)
  27:         {
  28:             if (string.IsNullOrEmpty(key))
  29:             {
  30:                 key = service.Name;
  31:             }
  32:  
  33:             var hostname = OperationContext.Current.Channel.LocalAddress.Uri.Host;
  34:             return string.Format("{0}:host={1}", key, hostname);
  35:         }
  36:  
  37:         public IHandler SelectHandler(string key, Type service, IHandler[] handlers)
  38:         {
  39:             return handlers.First(h => h.ComponentModel.Name == GetComponentKeyWithHostnameParameter(key, service));
  40:         }
  41:     }
  42: }
Remember that the IHandlerSelector interface has two methods; HasOpinionAbout and SelectHandler. In HasOpinionAbout we combine the name of the service (or the service type whatever is provided) with the hostname and ask the kernel if it can provide a component. If it can, we supply that component from the SelectHandler method.
 
In our configuration we can specify any components that we want to be chosen by hostname:
 
   1: public static IWindsorContainer Build()
   2: {
   3:     var container = new WindsorContainer();
   4:     container.Kernel.AddSubSystem(SubSystemConstants.NamingKey, new NamingPartsSubSystem());
   5:  
   6:     var debug = new ServiceDebugBehavior
   7:     {
   8:         IncludeExceptionDetailInFaults = true
   9:     };
  10:  
  11:     container.AddFacility<WcfFacility>()
  12:         .Register(
  13:             Component.For<IServiceBehavior>().Instance(debug),
  14:             Component.For<ILogger>().ImplementedBy<DefaultLogger>().Named("ILogger:host=blue.shop"),
  15:             Component.For<ILogger>().ImplementedBy<AlternativeLogger>().Named("ILogger:host=red.shop"),
  16:             Component
  17:                 .For<IBlogService>()
  18:                 .ImplementedBy<DefaultBlogService>()
  19:                 .Named("blogService")
  20:                 .LifeStyle.Transient
  21:         );
  22:  
  23:     container.Kernel.AddHandlerSelector(new HostBasedComponentSelector(container.Kernel));
  24:     GlobalKernel = container.Kernel;
  25:     return container;
  26: }
Here we specify two different components for the ILogger service which our DefaultBlogService has a dependency on; DefaultLogger and AlternativeLogger. When we call the service at http://blue.shop/BlogService.svc we will get a response from the DefaultBlogService composed with the DefaultLogger, when we call http://red.shop/BlogService.svc it will be composed with AlternativeLogger.
 
Note that we add the NamingPartsSubSystem before doing any other configuration. The HostBasedComponentSelector can be added afterwards.
 
Now I can happily add new host headers and, so long as I recycle my app pool, my service will respond as expected. Nice!

Friday, May 08, 2009

Parameterised component resolution with the Windsor NamingPartsSubSystem

Here’s a neat little trick I’ve recently learnt that my favourite IoC container can do.

Sometimes you need to resolve different components for the same service depending on some property. This is easy to do in Windsor with the NamingPartsSubSystem.

First register the subsystem with the AddSubSystem method, passing in a new instance of the NamingPartsSubSystem.

You can then give your components names differentiated by any number of parameters. For example we can have several components with the base name ‘thing’ and with a comma separated list of properties, in our case colour and version. The syntax is:

<name>:<key 1>=<value 1>[,<key n>=<value n>]

We can now resolve components based on any combination of those parameters. If more than one component matches, the container simply returns the first one to be registered.

Here’s a little test to demonstrate:

   1: using Castle.MicroKernel;
   2: using Castle.MicroKernel.Registration;
   3: using Castle.MicroKernel.SubSystems.Naming;
   4: using Castle.Windsor;
   5: using NUnit.Framework;
   6:  
   7: namespace Suteki.Blog.Tests.Spikes
   8: {
   9:     [TestFixture]
  10:     public class NamingPartsSubsystemSpike
  11:     {
  12:         [SetUp]
  13:         public void SetUp()
  14:         {
  15:         }
  16:  
  17:         [Test]
  18:         public void GetComponentsByHostname()
  19:         {
  20:             var container = new WindsorContainer();
  21:             container.Kernel.AddSubSystem(SubSystemConstants.NamingKey, new NamingPartsSubSystem());
  22:  
  23:             container.Register(
  24:                     Component.For<IThing>().ImplementedBy<Thing1>().Named("thing:colour=red,version=1"),
  25:                     Component.For<IThing>().ImplementedBy<Thing2>().Named("thing:colour=blue,version=1"),
  26:                     Component.For<IThing>().ImplementedBy<Thing3>().Named("thing:colour=red,version=2"),
  27:                     Component.For<IThing>().ImplementedBy<Thing4>().Named("thing:colour=blue,version=2")
  28:                 );
  29:  
  30:             var defaultThing = container.Resolve("thing");
  31:  
  32:             Assert.That(defaultThing, Is.Not.Null);
  33:             Assert.That(defaultThing, Is.TypeOf(typeof(Thing1)));
  34:  
  35:             var redThing = container.Resolve("thing:colour=red");
  36:  
  37:             Assert.That(redThing, Is.Not.Null);
  38:             Assert.That(redThing, Is.TypeOf(typeof(Thing1)));
  39:  
  40:             var blueThing = container.Resolve("thing:colour=blue");
  41:  
  42:             Assert.That(blueThing, Is.Not.Null);
  43:             Assert.That(blueThing, Is.TypeOf(typeof(Thing2)));
  44:  
  45:             var version2 = container.Resolve("thing:version=2");
  46:  
  47:             Assert.That(version2, Is.Not.Null);
  48:             Assert.That(version2, Is.TypeOf(typeof(Thing3)));
  49:  
  50:             var blueThingVersion2 = container.Resolve("thing:colour=blue,version=2");
  51:  
  52:             Assert.That(blueThingVersion2, Is.Not.Null);
  53:             Assert.That(blueThingVersion2, Is.TypeOf(typeof(Thing4)));
  54:         }
  55:  
  56:         private class IThing {}
  57:         private class Thing1 : IThing {}
  58:         private class Thing2 : IThing {}
  59:         private class Thing3 : IThing {}
  60:         private class Thing4 : IThing {}
  61:     }
  62: }

Thursday, May 07, 2009

Has this happened to you?

HasThisHappenedToYou

Me? At least three times :)

Wednesday, May 06, 2009

Windsor WCF Facility: MessageAction and MessageEnvelopeAction

This is the fifth in a series of posts featuring the WCF Facility:

Windsor WCF Integration
WCF / Windsor Integration: Using the perWebRequest lifestyle
WCF / Windsor Integration: Adding Behaviours
Atom feeds with the Windsor WCF Facility

Download the code for this post here:
http://static.mikehadlow.com/Suteki.Blog.zip

MessageAction and MessageEnvelopeAction provide an easy way to intercept WCF service or client operations.

In a previous post, I showed how we could configure WCF Behaviours using the WCF Facility. I commented that WCF Behaviours have a difficult API:

“As an aside, I can't help feeling that the WCF behaviour API is overly complex, it hardly invites you in. There's no way I would have worked out how to do this without looking at the documentation. Not at all the pit of success.”

If you want to simply process a message, or do some action before and after each operation, you first have to create an instance of IEndpointBehavior and then use it to register an IClientMessageInspector or an IDispatchMessageInspector.

Now there’s a much easier way. Craig Neuwirt, the author of the WCF Facility, has added a number of new concepts; MessageAction, MessageEnvelopeAction and MessageLifecyle. These make it very easy to intercept WCF operations.

Let’s use a MessageAction to intercept a WCF operation. Here’s a simple example:

 

   1: using System;
   2: using System.Collections;
   3: using System.ServiceModel.Channels;
   4: using Castle.Facilities.WcfIntegration.Behaviors;
   5:  
   6: namespace Suteki.Blog.ConsoleService.Wcf
   7: {
   8:     public class LifestyleMessageAction : AbstractMessageAction
   9:     {
  10:         private readonly string stateToken = Guid.NewGuid().ToString();
  11:  
  12:         public LifestyleMessageAction()
  13:             : base(MessageLifecycle.All)
  14:         {
  15:         }
  16:  
  17:         public override bool Perform(ref Message message, MessageLifecycle lifecycle, IDictionary state)
  18:         {
  19:             if (lifecycle == MessageLifecycle.IncomingRequest)
  20:             {
  21:                 state.Add(stateToken, "This state has been stored for the duration of the request");
  22:             }
  23:             if (lifecycle == MessageLifecycle.OutgoingResponse)
  24:             {
  25:                 Console.WriteLine(state[stateToken]);
  26:             }
  27:  
  28:             Console.WriteLine("Perform called at lifecycle: {0}", lifecycle);
  29:             return true;
  30:         }
  31:     }
  32: }

Simply create a class that inherits AbstractMessageAction, pass in the MessageLifecyle you want to intercept and implement the Perform method. The MessageLifecycle has the following values:

   1: /// <summary>
   2: /// Specifies the lifecycle of a message.
   3: /// </summary>
   4: [Flags]
   5: public enum MessageLifecycle
   6: {
   7:     /// <summary>
   8:     /// The outgoing request.
   9:     /// </summary>
  10:     OutgoingRequest = 0x01,
  11:     /// <summary>
  12:     /// The incoming response.
  13:     /// </summary>
  14:     IncomingResponse = 0x02,
  15:     /// <summary>
  16:     /// The outgoing request.
  17:     /// </summary>
  18:     IncomingRequest = 0x04,
  19:     /// <summary>
  20:     /// The incoming response.
  21:     /// </summary>
  22:     OutgoingResponse = 0x08,
  23:     /// <summary>
  24:     /// All incoming messages.
  25:     /// </summary>
  26:     IncomingMessages = IncomingRequest | IncomingResponse,
  27:     /// <summary>
  28:     /// All outgoing messages.
  29:     /// </summary>
  30:     OutgoingMessages = OutgoingRequest | OutgoingResponse,
  31:     /// <summary>
  32:     /// A solitic/response exchange.
  33:     /// </summary>
  34:     OutgoingRequestResponse = OutgoingRequest | IncomingResponse,
  35:     /// <summary>
  36:     /// A request/response exchange.
  37:     /// </summary>
  38:     IncomingRequestResponse = IncomingRequest | OutgoingResponse,
  39:     /// <summary>
  40:     /// All requests.
  41:     /// </summary>
  42:     Requests = IncomingRequest | OutgoingRequest,
  43:     /// <summary>
  44:     /// All requests.
  45:     /// </summary>
  46:     Responses = IncomingResponse | OutgoingResponse,
  47:     /// <summary>
  48:     /// All message.
  49:     /// </summary>,
  50:     All = IncomingMessages | OutgoingMessages
  51: }

You can choose to intercept any combination of client or server requests or responses. Here I’m passing MessageLifecycle.All, saying I want to listen to both requests and responses on both client and server components.

The Perform method is called on the MessageLifecycle steps you specify. Since I’m going to configure my LifestyleMessageAction on a server component and I’ve specified MessageLifecycle.All I’m expecting Perform to be called After the request is received by the server and before the reply is sent.

Perform takes the WCF Message, the MessageLifecycle and an IDictionary instance that you can use to pass state between message actions. Here I’ve stored a string value in the state dictionary when the request was received and retrieved it when the response was sent, so that we can see state being preserved through the lifetime of the call.

Here is the Windsor configuration:

   1: public static IWindsorContainer Build()
   2: {
   3:     return new WindsorContainer()
   4:         .AddFacility<WcfFacility>()
   5:         .Register(
   6:             Component.For<MessageLifecycleBehavior>(),
   7:             Component.For<LifestyleMessageAction>(), // adds this message action to all endpoints
   8:             Component
   9:                 .For<IBlogService>()
  10:                 .ImplementedBy<DefaultBlogService>()
  11:                 .Named("blogService")
  12:                 .LifeStyle.Transient
  13:                 .ActAs(new DefaultServiceModel()
  14:                     .AddEndpoints(WcfEndpoint
  15:                         .BoundTo(new NetTcpBinding())
  16:                         .At("net.tcp://localhost/BlogService")
  17:                         )),
  18:             Component
  19:                 .For<ILogger>()
  20:                 .ImplementedBy<DefaultLogger>()
  21:                 .LifeStyle.Transient
  22:         );
  23:    
  24: }

I’m serving my DefaultBlogService using the WcfFacility over a NetTcpBinding (see my previous WCF Facility posts for the details on the configuration). All MessageActions rely on the MessageLifecycleBehavior to register them with WCF. The MessageLifecycleBehavior is an IEndpointBehavior that hosts MessageActions so you need to register it with the container.

If you register your MessageAction as a component, as I have done here, it is applied to every operation of every service or client hosted by the WCF Facility. Alternatively, if you only want the MessageAction to apply to a particular endpoint, you can add it directly as an endpoint extension:

   1: public static IWindsorContainer Build()
   2: {
   3:     return new WindsorContainer()
   4:         .AddFacility<WcfFacility>()
   5:         .Register(
   6:             Component.For<MessageLifecycleBehavior>(),
   7:             Component
   8:                 .For<IBlogService>()
   9:                 .ImplementedBy<DefaultBlogService>()
  10:                 .Named("blogService")
  11:                 .LifeStyle.Transient
  12:                 .ActAs(new DefaultServiceModel()
  13:                     .AddEndpoints(WcfEndpoint
  14:                         .BoundTo(new NetTcpBinding())
  15:                         .At("net.tcp://localhost/BlogService")
  16:                         // adds this message action to this endpoint
  17:                         .AddExtensions(new LifestyleMessageAction()) 
  18:                         )),
  19:             Component
  20:                 .For<ILogger>()
  21:                 .ImplementedBy<DefaultLogger>()
  22:                 .LifeStyle.Transient
  23:         );
  24:    
  25: }

Running the simple console hosted service gives this result:

console_service

We can see that two operations were executed, one to add a post and one to return a post. We can see the console output for the IncomingRequest and the OutgoingResponse for each operation, and we can see that the state was persisted through the lifetime of the operation.

MessageAction provides the ideal place to implement operation lifetime concerns. I’m going to look at using it to implement a custom Windsor LifestyleManager and a UnitOfWork per operation component, much as Andreas Ohlund has done with WCF and StructureMap.

Tuesday, May 05, 2009

Atom feeds with the Windsor WCF Facility

This is the fourth in a series of posts featuring the WCF Facility:

Windsor WCF Integration
WCF / Windsor Integration: Using the perWebRequest lifestyle
WCF / Windsor Integration: Adding Behaviours

Today I’m going to show how easy it is to leverage the new atom support in that was introduced with 3.5 sp1 to provide feeds supplied by Windsor components.

Download the Sample Solution here:
http://static.mikehadlow.com/Suteki.Blog.zip

Let’s jump right in to the code. I’m going to use a blog example because it’s obviously a natural fit for atom, but you can use it to publish anything you want. Let’s say we have a Post class:

   1: using System;
   2:  
   3: namespace Suteki.Blog.Model
   4: {
   5:     public class Post : ModelBase
   6:     {
   7:         public string Title { get; set; }
   8:         public string Text { get; set; }
   9:         public DateTime CreatedDate { get; set; }
  10:  
  11:         public override string ToString()
  12:         {
  13:             return string.Format("Post Id: {0} Title: '{1}'", Id, Title);
  14:         }
  15:     }
  16: }

That’s pretty much what you’d expect. Now say we have an IBlogService that allows us to add and retrieve Posts:

   1: using Suteki.Blog.Model;
   2:  
   3: namespace Suteki.Blog.Service
   4: {
   5:     public interface IBlogService
   6:     {
   7:         Post[] GetPosts();
   8:         Post GetPost(string id);
   9:         void AddPost(Post post);
  10:     }
  11: }

Now let’s create a service contract for our atom feed:

   1: using System.ServiceModel;
   2: using System.ServiceModel.Syndication;
   3: using System.ServiceModel.Web;
   4:  
   5: namespace Suteki.Blog.RestService.Atom
   6: {
   7:     [ServiceContract]
   8:     public interface IAtomFeed
   9:     {
  10:         [OperationContract]
  11:         [WebGet(UriTemplate = "/")]
  12:         Atom10FeedFormatter GetPosts();
  13:     }
  14: }

The WebGet attribute was introduced with WCF 3.5 to make it easy to create RESTful web services and uses a URI templating scheme to route URLs to service methods. Here we are routing the root URL to our GetPosts method. Note that the GetPosts method returns Atom10FeedFormatter. This class knows how to format your items as an atom feed.

So far this is all straight from WCF, we haven’t brought the WCF Facility to the party yet. To tell the WCF Facility to supply the service instance, we need to create a specific AtomFeed.svc file. My one looks like this

   1: <%@ ServiceHost Service="atomFeed" 
   2: Factory="Castle.Facilities.WcfIntegration.WindsorServiceHostFactory`1[[Castle.Facilities.WcfIntegration.Rest.RestServiceModel, Castle.Facilities.WcfIntegration]], Castle.Facilities.WcfIntegration" %>

We tell WCF to use the WCF Facility’s host factory with its RestServiceModel. The bizarre square bracket syntax is simply the CLR notation for generics.  The service is specified as ‘atomFeed’, this tells the WCF Facility to resolve the component named ‘atomFeed’ from the Windsor container.

Next we have the Windsor configuration:

   1: using System.ServiceModel.Description;
   2: using Castle.Facilities.WcfIntegration;
   3: using Castle.MicroKernel.Registration;
   4: using Castle.Windsor;
   5: using Suteki.Blog.RestService.Atom;
   6: using Suteki.Blog.Service;
   7:  
   8: namespace Suteki.Blog.RestService.IoC
   9: {
  10:     public class ContainerBuilder
  11:     {
  12:         public static IWindsorContainer Build()
  13:         {
  14:             var debug = new ServiceDebugBehavior
  15:             {
  16:                 IncludeExceptionDetailInFaults = true
  17:             };
  18:  
  19:             return new WindsorContainer()
  20:                 .AddFacility<WcfFacility>()
  21:                 .Register(
  22:                     Component.For<IServiceBehavior>().Instance(debug),
  23:                     Component.For<IPostAtomFeedMapper>().ImplementedBy<DefaultPostAtomFeedMapper>(),
  24:                     Component
  25:                         .For<IAtomFeed>()
  26:                         .ImplementedBy<DefaultAtomFeed>()
  27:                         .Named("atomFeed")
  28:                         .LifeStyle.Transient,
  29:                     Component
  30:                         .For<IBlogService>()
  31:                         .ImplementedBy<DefaultBlogService>()
  32:                         .Named("blogService")
  33:                         .LifeStyle.Transient,
  34:                     Component.For<ILogger>().ImplementedBy<DefaultLogger>().LifeStyle.Transient
  35:                 );
  36:         }
  37:     }
  38: }

Note that we have a component named ‘atomFeed’ that is implemented by DefaultAtomFeed. The container will create an instance of DefaultAtomFeed to service the request.

   1: using System.ServiceModel.Syndication;
   2: using Suteki.Blog.Service;
   3:  
   4: namespace Suteki.Blog.RestService.Atom
   5: {
   6:     public class DefaultAtomFeed : IAtomFeed
   7:     {
   8:         private readonly IBlogService blogService;
   9:         private readonly IPostAtomFeedMapper postAtomFeedMapper;
  10:  
  11:         public DefaultAtomFeed(IBlogService blogService, IPostAtomFeedMapper postAtomFeedMapper)
  12:         {
  13:             this.blogService = blogService;
  14:             this.postAtomFeedMapper = postAtomFeedMapper;
  15:         }
  16:  
  17:         public Atom10FeedFormatter GetPosts()
  18:         {
  19:             var posts = blogService.GetPosts();
  20:             return new Atom10FeedFormatter(postAtomFeedMapper.Map(posts));
  21:         }
  22:     }
  23: }

Note that it has dependencies on both the IBlogService, that we saw above, and IPostAtomFeedMapper. IPostAtomFeedMapper is responsible for mapping the array of Post instances returned from IBlogService to a SyndicationFeed instance. SyndicationFeed is another WCF type to support feeds and is consumed by the Atom10FeedFormatter. Here is the IPostAtomFeedMapper implementation:

   1: using System.Collections.Generic;
   2: using System.ServiceModel.Syndication;
   3: using Suteki.Blog.Model;
   4:  
   5: namespace Suteki.Blog.RestService.Atom
   6: {
   7:     public class DefaultPostAtomFeedMapper : IPostAtomFeedMapper
   8:     {
   9:         public SyndicationFeed Map(Post[] posts)
  10:         {
  11:             var items = new List<SyndicationItem>();
  12:  
  13:             foreach (var post in posts)
  14:             {
  15:                 var item = new SyndicationItem
  16:                 {
  17:                     Id = post.Id.ToString(),
  18:                     Title = new TextSyndicationContent(post.Title),
  19:                     Content = new TextSyndicationContent(post.Text),
  20:                     PublishDate = post.CreatedDate
  21:                 };
  22:                 items.Add(item);
  23:             }
  24:  
  25:             return new SyndicationFeed(items);
  26:         }
  27:     }
  28: }

And it’s as simple as that. No need for any Web.config configuration. When I run the service and browse to its URL with Firefox I see the familiar atom feed page:

 atom_feed

Sunday, May 03, 2009

Brighton ALT.NET Beers, Tuesday 5th May at the Prince Albert

Iain Holder has organised the second Brighton ALT.NET beers. It’s going to be at the Prince Albert again on Tuesday 5th May at 7pm. The pub is very easy to find, just below Brighton station on Trafalgar street  (30 seconds walk).

image

More information on Iain’s blog.

The first one was a great success; a full house and some really good discussions. If you’re a keen .NET developer in Brighton it’s not to be missed.