CodeProject, F#

F#2 FSI Environment

As most of you know I am a C# kind of guy.  So whenever I want to do a bit of mucking about where I just want to try something out I will typically just spin up an instance of LINQPad and try stuff out in there. If things grow too much and I need more control over the experimenting, I will abandon LINQPad and will spin up a ConsoleApplication in Visual Studio. Both of these approaches do work fine, but wouldn’t it be nice if there was some sort of environment where you could try stuff out within Visual Studio itself, without even needing to create a new project of any kind.

Luckily in F# there is just that. There is a absolutely brilliant tool called the “F# interactive window” (FSI), which you can find by using Visual Studio (I am using VS 2012) like this:

image

So once you open the F# Interactive window, you should see something like this:

image

Now this may not look that grand yet, but this window allows you to do a great many things pretty easily. It can be used for rapid prototyping, and inspection purposes if you like.

So you can see that you have the prompt > which is waiting for some input from you. So how do I give it some input?

Giving Input

All you need to do within the F# Interactive window to get some input accepted is to end your line with 2 semi colons “;;”.

Some valid examples of valid input are shown below

Declaring a function that will take a value and square it (note we did not specify the type of x)

let squarer x = x * x;;

And now let’s declare a variable that will hold the return value of calling the “squarer” function. This is easily done as follows:

let squared = squarer 10;;

Viewing Data

Should we wish to view data we can also evaluate things in a similar manner. So assuming we have just typed in the values above, we would have the following in scope:

  1. A squarer function
  2. A Int value bound the squared variable

So to evaluate one of these say the “squared” variable, we can simply type something like this into the FSI prompt:

squared;;

What happens when we run that line in the FSI is that the value is printed to the FSI window, something like this:

val it : int = 100

Where it can be seen that the value is indeed 100, which is the result of the earlier call the “squarer” function that was created in the FSI window.

 

A Word About Scope

One of the other key benefits of using the FSI window is to do with scope.

To understand what I mean by that, say we had typed this function into the FSI window

let someMathsFunction x = x + x
let add2ToIt x = (someMathsFunction x) + 2

And then I evaluated the results by doing something like this in the FSI window

add2ToIt 12;;

Where the result would be this:

val it : int = 26

All good so far. But les say I then did this in the FSI window, where I changed the way the “someMathsFunction” works, say I get it to triple the input instead

let someMathsFunction x = x * 3;;

And then I tried to evaluate the original add2ToIt function, which should be doing something like this now:

let someMathsFunction x = x * 3;;
let add2ToIt x = (someMathsFunction x) + 2;;

Which when asked to evaluate (say with the number 12),  should yield the following result

12 * 3 + 2 = 38

But instead when I run things (not shown here as same output as previously seen) I still get the old result of 26

This is down to scope within the FSI. If we told the FSI that both the function that changed (“someMathsFunction” in this case) and the one that make use of it (“add2ToIt” in this case), should be defined and rebound using the let keyword, we should get what we are after ( i.e. the correct result of 38)

This may sound complex, but what I mean is, if we run this in the FSI window instead:

let someMathsFunction x = x * 3;;
let add2ToIt x = (someMathsFunction x) + 2;;

and then we evaluate that as follows:

> add2ToIt 12;;
val it : int = 38

We now do indeed get what we asked for. Why is this happening? Why didn’t we get it before?

Well it is to do with the bind keyword in F#, and the fact that the bind needs to be set to the new range. Don’t worry to much about this for now, we will get onto this is subsequent posts. For now it is probably enough to be aware of this feature.

Last cool thing before we depart

Before we finish up on this post, I just wanted to mention that you can also use the FSI window along with a F# script file should you wish to try things out quickly.

Say I had a F# script file (FSX) with the following code in it

open System

let squareRootMe x = System.Math.Sqrt(x)

And I wanted to try that out in the FSI, I can simply highlight the lines / section of the code, and choose to execute it in the FSI window.

image

It is then in scope within the FSI window. Which means I can use the function, as demonstrated here:

>  let x =    squareRootMe 144.0;;

val x : float = 12.0
CodeProject, F#

F# 1 : Hello World

So this is the 1st post in my F# series. So what are we going to cover then? Well as many programmers well know, it is customary to start with a “Hello World” example.

So we will be doing just that. So without further ado, what does it take to create a stand alone “Hello World” app in F#.

Well here it is:

open System

[<EntryPoint>]
let main argv = 
    printfn "Hello World" 
    Console.ReadLine() |> ignore
    0

Now that might not seem like enough to talk about, but it is, and further more it actually has enough content to allow us to talk about a few core F# principles to boot.

So what exactly is going on here?

Well since this is a stand alone application, we obviously need an entry point (just as we would for any other .NET language. So how is the entry point defined? Well it’s much the same as it is with other .NET languages, we have a main method (or function in F# lingo) that takes an string  array, and we use the [<EntryPoint>] attribute to indicate that the method that has this attribute is the main one. The compiler and Visual Studio love us for this.

Even in that sentence alarm bells , or at least some sort of spider sense should be going off. So we said there was a main function that that takes an array of string array. All I can see there is a variable called “argv” I certainly can’t see any string array. This “argv” variable is clearly the string array that we would expect, but why doesn’t it have a type….Mmm interesting.

In F# there is a very very good type inference system, which means in a lot of cases you may choose to leave out the type all together and F# will correctly infer it. You are of course still able to fully declare the type of an input variable if you wanted to, where it would typically take the form

(variableName :variableType)

So taking the “argv” example stated above, we could instead declare the above program like this, and that would be fine:

open System

[<EntryPoint>]
let main (argv :string[]) = 
    printfn "Hello World" 
    Console.ReadLine() |> ignore
    0

Can you see that we fully qualified the name of the input variable with its type, which is this case is a string[] array.

What else is of interest there? Well like I say there is more to talk about than you think.

Why do I have a line that has this strange |> ignore incantation at the end of it. What it that all about?

Well since this is a F# Console Application, I wanted the application not to exit until the user types a character. So I need to do 2 things

  1. Open the “System” namespace, which allows me to use the types in the “System” namespace, much the same as it would if I used “using System” in C#, or “Imports System” in VB .NET”.
  2. Since F# is a functional language it will complain if the actual function (in this case the “main” function does not return a value, so I must choose to use the forward pipe operator to pipe the output of the function of the left, which is in this case a “Console.ReadLine(…)” which may return a string, to an “ignore” function. Which effectively means return ()  ( that is F#’s way of saying void, but it calls it Unit i.e. don’t care). This explicitly tells F# to ignore the result of the “Console.ReadLine(..)” method call.

For example this is what the code would look like if I chose to not include the |> ignore incantation

image

To the regular C# / VB .NET programmer you may not see what this prompt is talking about here. But F# is quite rigid about what a function can and can’t  do. And one thing a function MUST ALWAYS do is return a result. In the case of the “main” function, the result is expected to  be an integer value of 0. But what about the case of the “Console.ReadLine(..)”. OK in this case it is not a big deal and we are not interested in the result, and the program will still run and work just fine if we omit the |> ignore, but if you are truly not interested in the result you should get in the habit of using the |> ignore combo. Just in case you are wondering, the forward pipe operator “|>” will pipe the return value of the left hand expression to the right hand function, which in this case equates to “take the return value of Console.Readline(…) and pipe it to ignore, as no one cares”.  Don’t worry if this means nothing to you at this stage, we will see more on this later.

The last thing I need to do is ensure that the F# function always returns a value, this is done in the line where you simply see a 0 line. This is enough for F# to realise this is the return value of “0” which the type inference system will deduce is an Int value of 0. The reason the F# compiler knows this is the return value is that in this case, this is the last statement, so it MUST be the return value. Obviously this could get more complex with conditional if, else etc logic. The important thing to note is that in F# a function MUST ALWAYS return a value, and in this case since the 0 Int value was the last line encountered (albeit things could be more complex, and they will be jest not yet) it is used as the return value. You can of course choose to return Unit which is done by using “()”, which is effectively return nothing (void if you like)

One other thing I would like to mention for this trivial example, is that whitespace plays a pivotal role in F# development.

For example suppose my trivial example looked like this in the editor (in my case Visual Studio 2012) :

image

This is a tiny program and ALL I have done is delete some whitespace at the beginning of the “printfn” line. Mmmm seems like the F# compiler did not like that at all. Yes that is a fair assessment.

In F# whitespace is VERY VERY important, so play nice with it, otherwise get used to debugging cryptic errors such as the one shown above, which is caused by a simple issue of incorrect semantic white space.

Anyway that is the “Hello World” example. Until we meet again next time, I bid you all fair well.

CodeProject, F#

F# For Beginners Series

Over the past couple of months I have been quite. This is due to the fact that I have been attempting to learn a new language. Namely F#. Now I spend most of my time as a regular .NET developer. Ok F# is part of the .NET family, but its is way more functional than any of the other .NET languages, so it has been quite the ride.

It has been a ride that I have and still am enjoying. Now I had this crazy idea that it might be fun to document this ride. The ride (the learning process ) is an ongoing one, and one that will likely take me many years to master. However at the early stages I thought it may help other .NET developers that are looking to start with F# get into it at a somewhat slower pace.

With that in mind I will be doing a bunch of blog posts on F#. Now I am not saying that these will be useful (especially to seasoned F# users), but I hope they will be, nor am I claiming to be a F# guru. I am clearly not, I am a mere fledgling, which is in fact the point.

I will be writing posts assuming the reader knows absolutely nothing about F#.

So what can be gained from reading such a series of posts? Well I am hoping that by watching someone else’s journey from C# into F# it will cover most of the salient points that one would want to cover.

So what will be covered in this series of posts exactly?

Well the exact content is yet to be decided but it will certainly evolve along the way, and when it does I will update a master page (which you can find by looking at the top level menus to this site) with the new links as they appear

So  hope this helps someone. Let’s get on with it then

Uncategorized

A Look At NServiceBus Sagas

I have just written a small article that talks about how to use the interprocess bus NServiceBus to perform potentially long running workflows (Called Sagas in NServiceBus).

The article talks about

  • NServiceBus general ideas/principles
  • How to host NServiceBus
  • How to set up a commander
  • How to set up a subscriber
  • How to work with Sagas
  • How to persist Sagas
  • How to deal with Saga data

If you want to know more you can read the full article over here:

http://www.codeproject.com/Articles/731007/A-Look-At-NServiceBus-Sagas

I think this is quite a useful article to get you up and running with NServiceBus

 

 

 

CodeProject, Uncategorized

AutoMocking Container

At work I am lucky enough to work with a few bright chaps (sadly some of them are a lot youger than me, which is making me question my existence 😦 , but on the other hand it is always good to learn new things).

One of those new things for me happened the other day, where this dude at work showed me MSpec for TDD/BDD, and I have to say it was pretty awesome. The thing that I liked the most was the “AutoMocking” feature

So what is this “AutoMocking” that I am talking about, and why is it cool? Well quite simply it eliviates the brittle relationship with code and tests in their infancy, and allows tests to create constructor injection parameters automatically

I should point out that this pattern really suits new code bases, that may still be a bit in flux, it is not really that much use for well established code bases that have been around and settled for a while

It is also worth noting that this pattern can be used with code that doesn’t use any IOC/dependency injection at all, it is purely a testing concern

So what is it all about?

Well say you have this class

public class Autobooker
{
    private readonly ILogger logger;
    private readonly IRateProvider rateProvider;
    private readonly IBooker booker;

    public Autobooker(ILogger logger, IRateProvider rateProvider, IBooker booker)
    {
        this.logger = logger;
        this.rateProvider = rateProvider;
        this.booker = booker;
    }


    public void BookDeal(string ccy1, string ccy2, decimal amount)
    {
        logger.Log(string.Format("Booked deal for {0}/{1}", ccy1, ccy2));
        decimal rate = rateProvider.GetRate(string.Join("", ccy1, ccy2));
        booker.Book(ccy1, ccy2, rate, amount);

    }
}

Which you may write a test case for something like this (I am using NUnit and Moq, but you may prefer you own tools to these)

[TestFixture]
public class TestCases
{
    private IWindsorContainer container;

    [SetUp]
    public void SetUp()
    {
        container = new WindsorContainer();
        container.Install(new BookerInstaller());
    }

    [TestCase("EUR", "GBP", 1500)]
    [TestCase("GBP", "EUR", 2200)]
    public void TypicalTestCase(string ccy1, string ccy2, decimal amount)
    {
        //setup
        string ccyPair = string.Join("", ccy1, ccy2);
        var rate = 1;
        var loggerMock = new Mock<ILogger>();
        var rateProviderMock = new Mock<IRateProvider>();
        var bookerMock = new Mock<IBooker>();

        rateProviderMock
            .Setup(x => x.GetRate(ccyPair)).Returns(1);

        var autobooker = new Autobooker(loggerMock.Object, rateProviderMock.Object, bookerMock.Object);
        autobooker.BookDeal(ccy1, ccy2, amount);

        //assert
        loggerMock
            .Verify(x => x.Log(string.Format("Booked deal for {0}/{1}", ccy1, ccy2)),
                Times.Exactly(1));

        rateProviderMock
            .Verify(x => x.GetRate(string.Join("", ccy1, ccy2)), Times.Exactly(rate));

        bookerMock
            .Verify(x => x.Book(ccy1, ccy2, rate, amount), Times.Exactly(1));
    }
}

The problem with this code is that it is extremely coupled to the design. What would happen if the Autobooker class needed to take a new constructor dependency say something like this

public class Autobooker
{
    private readonly ILogger logger;
    private readonly IRateProvider rateProvider;
    private readonly IBooker booker;
    private readonly IPricer pricer;

    public Autobooker(ILogger logger, IRateProvider rateProvider, IBooker booker, IPricer pricer)
    {
        this.logger = logger;
        this.rateProvider = rateProvider;
        this.booker = booker;
        this.pricer = pricer;
    }
}

This should immediately ring alarm bells that your existing test cases will now break, but what can we do about it? This is where “AutoMocking” can help. Let us take a look at this shall we.

So the first step is to decide on a nice IOC container that you think is fit for the job. For me this is Castle Windsor. So that is that decision made, so what do we need to do now that we have made that decision? Well all we really need to do is get it to automatically create our Mocks for us. SO what does that look like? Well for me it looks like this

public class AutoMoqServiceResolver : ISubDependencyResolver
{
    private IKernel kernel;

    public AutoMoqServiceResolver(IKernel kernel)
    {
        this.kernel = kernel;
    }

    public bool CanResolve(
        CreationContext context,
        ISubDependencyResolver contextHandlerResolver,
        ComponentModel model,
        DependencyModel dependency)
    {
        return dependency.TargetType.IsInterface;
    }

    public object Resolve(
        CreationContext context,
        ISubDependencyResolver contextHandlerResolver,
        ComponentModel model,
        DependencyModel dependency)
    {
        var mock = typeof(Mock<>).MakeGenericType(dependency.TargetType);
        return ((Mock)kernel.Resolve(mock)).Object;
    }
}

The next step is to create some sort of IOC registration for the system under test (SOT), which for me means the Autobooker type. So we do that as follows

public class BookerInstaller : IWindsorInstaller
{
    public void Install(
        IWindsorContainer container,
        IConfigurationStore store)
    {
        container.Kernel.Resolver.AddSubResolver(new AutoMoqServiceResolver(container.Kernel));
        container.Register(Component.For(typeof(Mock<>)));

        container.Register(Classes
            .FromAssemblyContaining<Booker.Autobooker>()
            .Pick()
            .WithServiceSelf()
            .LifestyleTransient());
    }
}

With that all in place I can now write non brittle code, that will get the object I want to test from the IOC container, where all its dependencies will try to be satified by the automocking IOC container. So my test case now looks like this

[TestCase("EUR", "GBP", 1500)]
[TestCase("GBP", "EUR", 2200)]
public void TestBooking(string ccy1, string ccy2, decimal amount)
{
    var autobooker = container.Resolve<Autobooker>();
    string ccyPair = string.Join("", ccy1, ccy2);
    var rate = 1;
            
    //arrange
    container.Resolve<Mock<IRateProvider>>()
        .Setup(x => x.GetRate(ccyPair)).Returns(1);

    autobooker.BookDeal(ccy1,ccy2,amount);

    //assert
    container.Resolve<Mock<ILogger>>()
        .Verify(x => x.Log(string.Format("Booked deal for {0}/{1}", ccy1, ccy2)),
            Times.Exactly(1));

    container.Resolve<Mock<IRateProvider>>()
        .Verify(x => x.GetRate(string.Join("", ccy1, ccy2)), Times.Exactly(rate));
            
    container.Resolve<Mock<IBooker>>()
        .Verify(x => x.Book(ccy1,ccy2,rate,amount), Times.Exactly(1));

}

See how I no longer need to declare the mocks, I just define their behavior, which I think is cool

C#, CodeProject

Awaitable Console Application

The other days someone posted some code about how to make Async/Await easier to work with. What they went for was not correct, and looked more like RXs model of OnNext/OnError/OnCompleted. The reason it was wrong is that it did not support awaiting.

As a rule any Asyn code you write WILL need synchronizing at some point, so must be awaitable. This is the reason why async void is a very very dodgy thing and should only be used for event handlers, but lets not even get into that.

Now when I was talking to the chap who wrote the original stuff I pointed out more typical use case would have been to do something like this

class Program
{
    static void Main(string[] args)
    {

        new Program().Backup();
        Console.ReadLine();
    }


    public async void Backup()
    {
        var backupStatus = await BackupAsync();
    }


    public async Task<string> BackupAsync()
    {
        return await Task.Run(() => "groovy");
    }

}

Another eagle eyed reader pointed out that you should never use async void (I was doing that to be as much in line with the original posters code), and that the only reason my code worked was due to the use of the Console.ReadLine() which was blocking the main thread.

I did know that I should never really use async void, so I set about trying to post a better version of this. One important note here is that I am using a ConsoleApplication. So I tried this

class Program
{
    private  static async void Main(string[] args)
    {
        await new Program().Backup();
    }


    public async Task Backup()
    {
        var backupStatus = await BackupAsync();
        await Task.Delay(5000); //simulate some work
        Console.WriteLine(backupStatus);
    }


    public async Task<string> BackupAsync()
    {
        return await Task.Run(() => "groovy");
    }
}

The compiler complained about this, and would not allow a async void main method. This is the error

‘NonAwaitingConsoleApplication.Program.Main(string[])’: an entry point cannot be marked with the ‘async’ modifier

Ok so how about this one then

class Program
{
    private static void Main(string[] args)
    {
        Task.Run(() => MainAsync(args)).Wait();
    }

    static async void MainAsync(string[] args)
    {
        Console.WriteLine(DateTime.Now.ToLongTimeString());
        await new Program().Backup();
        Console.WriteLine(DateTime.Now.ToLongTimeString());
    }

    public async Task Backup()
    {
        var backupStatus = await BackupAsync();
        await Task.Delay(5000); //simulate some work
        Console.WriteLine(backupStatus);
    }


    public async Task<string> BackupAsync()
    {
        return await Task.Run(() => "groovy");
    }
}

And that exited straight away…mmmmm. Interesting. The reason for this, is that there is no SynchronizationContext in a ConsoleApplication. So the thread is simply returned to the OS, and the app exits prematurely. Not quite what we are after. What can we do?

Well luckily there is a very clever chap (who I highly rate) called Stephen Cleary, who has written a nice set of Extensions which is also written by Stephen Toub (he knows his onions for sure), so I have full trust in this library. It is called NitoAsyncEx. It is also available via NuGet : Nito.AsyncEx

Anyway with this in place we can now create an Awaiting ConsoleApplication like this

internal class Program
{
    private static void Main(string[] args)
    {
        AsyncContext.Run(() => MainAsync(args));
    }

    static async void MainAsync(string[] args)
    {
        Console.WriteLine(DateTime.Now.ToLongTimeString());
        await new Program().Backup();
        Console.WriteLine(DateTime.Now.ToLongTimeString());
    }

    public async Task Backup()
    {
        var backupStatus = await BackupAsync();
        await Task.Delay(5000); //simulate some work
        Console.WriteLine(backupStatus);
    }


    public async Task<string> BackupAsync()
    {
        return await Task.Run(() => "groovy");
    }
}

Notice the use of the AsyncContext that is the NitoAsyncEx magic class that makes it all possible. I urge you to have a look inside that class (you can do so using Reflector or via the Codeplex site source tab), and see how it works. Stephen is doing quite a bit on your behalf, like ensuring there is a valid SynchronizationContext. Please have a look at it. In fact look at it all its a very useful library

Which when run produces the following output, as expected, then exits (as expected)

  • 10:52:21
  • groovy
  • 10:52:26
C#, CodeProject

XmlSerializer : Serializing list of interfaces

At work I was stuck with a small problem when working with the XmlSerializer which I have not been using that much of late. Anyway I started out with something like this small demo program below

class Program
{
    static void Main(string[] args)
    {

        Order order = new Order
        {
            Products = new List<Product> {
                new Product {
                    Id =1,
                    Name = "Dummy1",
                    Quantity=1
                }
            }
        };

        //serialize
        var xmlSerializer = new XmlSerializer(typeof(Order));
        var stringBuilder = new StringBuilder();
        var xmlTextWriter = XmlTextWriter.Create(stringBuilder,
            new XmlWriterSettings { NewLineChars = "\r\n", Indent = true });
        xmlSerializer.Serialize(xmlTextWriter, order);
        var finalXml = stringBuilder.ToString();

        //deserialize
        xmlSerializer = new XmlSerializer(typeof(Order));
        var xmlReader = XmlReader.Create(new StringReader(finalXml));
        var deserializedOrder = (Order)xmlSerializer.Deserialize(xmlReader);

        Console.ReadLine();
    }
}

[XmlRoot]
public class Order
{
    public List<Product> Products { get; set;}
}

Where I would get this Xml when I serialized the Order object I had in play.

<?xml version="1.0" encoding="utf-16"?>
<Order xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Products>
    <Product>
      <Id>1</Id>
      <Name>Dummy1</Name>
      <Quantity>1</Quantity>
    </Product>
  </Products>
</Order>

And I would get this back when I deserialized the Xml back into an Order object

image

All cool so far. However what I then wanted to to introduce a new property on my Order that held a list in interfaces, something like shown below

{
    static void Main(string[] args)
    {

        Order order = new Order
        {
            Products = new List<Product> {
                new Product {
                    Id =1,
                    Name = "Dummy1",
                    Quantity=1
                }
            },
            Dispatchers = new List<IDispatcher> {
                new FileDispatcher()
            }
        };
    .....
    .....
    .....

        Console.ReadLine();
    }
}

[XmlRoot]
public class Order
{
    public List<Product> Products { get; set;}
    public List<IDispatcher> Dispatchers { get; set; }
}

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Quantity { get; set; }
}

public interface IDispatcher
{
    string Channel { get; set; }
    void Dispatch();
}

public class FileDispatcher : IDispatcher
{
    public string Channel { get; set; }

    public void Dispatch()
    {
        //This would do something in real code
    }
}

public class EmailDispatcher : IDispatcher
{
    public string Channel { get; set; }

    public void Dispatch()
    {
        //This would do something in real code
    }
}

So the code looks fine, it compiles nicely (always good start). So I then tried to serialize it, and got this

image

Mmm not great, so I had a think about this. Ok what about if we take control of the xml Serialization/Deserialization process ourselves. Should be easy enough to do, all we need to do it implement the IXmlSerializable interface. So lets see what the new code would look like if we went down this path shall we

public class Order
{
    public List<Product> Products { get; set;}
    public ListOfIDispatcher Dispatchers { get; set; }
}

public class ListOfIDispatcher : List<IDispatcher>, IXmlSerializable
{
    public ListOfIDispatcher() : base() { }

    public System.Xml.Schema.XmlSchema GetSchema() { return null; }

    public void ReadXml(XmlReader reader)
    {
        reader.ReadStartElement("Dispatchers");
        while (reader.IsStartElement("IDispatcher"))
        {
            Type type = Type.GetType(reader.GetAttribute("AssemblyQualifiedName"));
            XmlSerializer serial = new XmlSerializer(type);

            reader.ReadStartElement("IDispatcher");
            this.Add((IDispatcher)serial.Deserialize(reader));
            reader.ReadEndElement();
        }
        reader.ReadEndElement();
    }

    public void WriteXml(XmlWriter writer)
    {
        foreach (IDispatcher dispatcher in this)
        {
            writer.WriteStartElement("IDispatcher");
            writer.WriteAttributeString("AssemblyQualifiedName", dispatcher.GetType().AssemblyQualifiedName);
            XmlSerializer xmlSerializer = new XmlSerializer(dispatcher.GetType());
            xmlSerializer.Serialize(writer, dispatcher);
            writer.WriteEndElement();
        }
    }
}

So I added a new class an altered the Order class to use my new class. Then I tried to serialize things again, and now I get this XML

<?xml version="1.0" encoding="utf-16"?>
<Order xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Products>
    <Product>
      <Id>1</Id>
      <Name>Dummy1</Name>
      <Quantity>1</Quantity>
    </Product>
  </Products>
  <Dispatchers>
    <IDispatcher AssemblyQualifiedName="XmlSerialization.FileDispatcher, XmlSerialization, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
      <FileDispatcher>
        <Channel>c:\temp\file001.txt</Channel>
      </FileDispatcher>
    </IDispatcher>
  </Dispatchers>
</Order>

Ah much better, but does it deserialize?…..Mmm well yes it does, here you go. As I say it have been a while for me an the XmlSerializer, I think if you used an abstract class and registered some known types somehow that would also work. Anyway I happy with this and hope it helps someone out there

image

For completeness here is the full listing of everything in its final state

class Program
{
    static void Main(string[] args)
    {

        Order order = new Order
        {
            Products = new List<Product> {
                new Product {
                    Id =1,
                    Name = "Dummy1",
                    Quantity=1
                }
            },
            Dispatchers = new ListOfIDispatcher {
                new FileDispatcher()
                {
                    Channel = @"c:\temp\file001.txt"
                }
            }
        };

        //serialize
        var xmlSerializer = new XmlSerializer(typeof(Order));
        var stringBuilder = new StringBuilder();
        var xmlTextWriter = XmlTextWriter.Create(stringBuilder,
            new XmlWriterSettings { NewLineChars = "\r\n", Indent = true });
        xmlSerializer.Serialize(xmlTextWriter, order);
        var finalXml = stringBuilder.ToString();

        //deserialize
        xmlSerializer = new XmlSerializer(typeof(Order));
        var xmlReader = XmlReader.Create(new StringReader(finalXml));
        var deserializedOrder = (Order)xmlSerializer.Deserialize(xmlReader);

        Console.ReadLine();
    }
}

[XmlRoot]
public class Order
{
    public List<Product> Products { get; set;}
    public ListOfIDispatcher Dispatchers { get; set; }
}

public class ListOfIDispatcher : List<IDispatcher>, IXmlSerializable
{
    public ListOfIDispatcher() : base() { }

    public System.Xml.Schema.XmlSchema GetSchema() { return null; }

    public void ReadXml(XmlReader reader)
    {
        reader.ReadStartElement("Dispatchers");
        while (reader.IsStartElement("IDispatcher"))
        {
            Type type = Type.GetType(reader.GetAttribute("AssemblyQualifiedName"));
            XmlSerializer serial = new XmlSerializer(type);

            reader.ReadStartElement("IDispatcher");
            this.Add((IDispatcher)serial.Deserialize(reader));
            reader.ReadEndElement();
        }
        reader.ReadEndElement();
    }

    public void WriteXml(XmlWriter writer)
    {
        foreach (IDispatcher dispatcher in this)
        {
            writer.WriteStartElement("IDispatcher");
            writer.WriteAttributeString("AssemblyQualifiedName", dispatcher.GetType().AssemblyQualifiedName);
            XmlSerializer xmlSerializer = new XmlSerializer(dispatcher.GetType());
            xmlSerializer.Serialize(writer, dispatcher);
            writer.WriteEndElement();
        }
    }
}

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Quantity { get; set; }
}

public interface IDispatcher
{
    string Channel { get; set; }
    void Dispatch();
}

public class FileDispatcher : IDispatcher
{
    public string Channel { get; set; }

    public void Dispatch()
    {
        //This would do something in real code
    }
}

public class EmailDispatcher : IDispatcher
{
    public string Channel { get; set; }

    public void Dispatch()
    {
        //This would do something in real code
    }
}