F# – XmlSerializer, Record types and [CLIMutable]

Yan Cui

I help clients go faster for less using serverless technologies.

I talked about the XML and JSON serialization of F# types in a previous post, and since then F# 3.0 has been released and a new [CLIMutable] was quietly added amidst the hype surrounding the awesome type providers!

 

CLIMutable Attribute

When applied to a F# record type, the CLIMutable attribute tells the F# compiler to generate a default parameterless constructor as well as property getters and setters so that when working with the record type from other .Net languages it’ll appear as a pretty standard, mutable CLI type that you’d expect.

However, when working in F#, the normal rules as far as record types are concerned still apply – immutability by default, pattern matching, cloning using the with keyword, etc.

For a simple record type Person, let’s have a look at the compile code with and without the CLIMutable attribute:

image image

Without the CLIMutable attribute, this is how the record type is normally compiled:

image

With the CLIMutable attribute applied, things look a lot different:

image

That’s all well and good, but why is this useful you might ask?

Because many serializers, such as the BCL’s XmlSerializer (as well as other serializers available in the open source space) only work with types that has a default constructor and contains property setters.

 

XmlSerializer and Record types

Unlike the DataContractSerializer which only requires a type to be decorated with a Serializable or DataContract attribute, the XmlSerializer on the other hand, also requires the type to define a parameterless constructor.

Whilst both serializers generate XML outputs, DataContractSerializer is intended for marshalling data (that conforms to a ‘contract’) for transportation over the wire and therefore less concerned with readability of its output and offers little option for you to customize the generated XML. It’s therefore quite happy to spit out rather unreadable XML for our Person record type above:

 

<FSI_0004.Person xmlns=”http://schemas.datacontract.org/2004/07/”  xmlns:i=”http://www.w3.org/2001/XMLSchema-instance”><Age_x0040_>30</Age_x0040_><Name_x0040_>Yan Cui</Name_x0040_></FSI_0004.Person>

 

Meanwhile, in the land of the XmlSerializer, its sole purpose of existence is to generate XML and offers a platoon of options to help ensure its output meets your functional and aesthetic needs. By default it’ll generate nice, indented output for our CLIMutable version of Person record type:

 

<?xml version=”1.0″?>

<Person xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:xsd=”http://www.w3.org/2001/XMLSchema”>

  <Name>Yan Cui</Name>

  <Age>30</Age>

</Person>

 

In addition, you can customize the XML output using the normal XML-related attributes:

image

<?xml version=”1.0″?>

<Person xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:xsd=”http://www.w3.org/2001/XMLSchema” PersonName=”Yan Cui”>

  <PersonAge>30</PersonAge>

</Person>

 

OSS Serializers

Of the OSS JSON serializers I benchmark regularly, JSON.Net (v4.5.11 tested) works with both normal and CLIMutable record types from F#. ServiceStack.Text (v3.9.37 tested) doesn’t work with ‘vanilla’ record types on deserialization (fields are left with default values), but you can workaround by making the fields mutable or add the CLIMutable attribute to the type.

 

I hope this proves to be useful to you, and if like us you have a lot of C# code hanging around just to get pretty XML out of your F# record types, dare I say it’s about to throw away those C# code! Winking smile


 

Whenever you’re ready, here are 4 ways I can help you:

  1. If you want a one-stop shop to help you quickly level up your serverless skills, you should check out my Production-Ready Serverless workshop. Over 20 AWS Heroes & Community Builders have passed through this workshop, plus 1000+ students from the likes of AWS, LEGO, Booking, HBO and Siemens.
  2. If you want to learn how to test serverless applications without all the pain and hassle, you should check out my latest course, Testing Serverless Architectures.
  3. If you’re a manager or founder and want to help your team move faster and build better software, then check out my consulting services.
  4. If you just want to hang out, talk serverless, or ask for help, then you should join my FREE Community.

 


3 thoughts on “F# – XmlSerializer, Record types and [CLIMutable]”

  1. Pingback: F# Weekly #9, 2013 | Sergey Tihon's Blog

  2. Hello,

    There are also auto-properties in F# 3.0:

    type Person(name, age) =
    member val Name = name with get, set
    member val Age = age with get, set

  3. theburningmonk

    @Thorium –

    You’re right, but it means you’d introduce mutability into your F# code just to facilitate requirements of particular serializers.

    In general, I’d avoid mutability (which is not idiomatic functional style) unless have to or for performance reasons. Also, record types are much easier to work with (pattern match support ;-), etc.) in F# so where possible I prefer record types over class types, with the obvious exceptions of when you need to use inheritance or struct types, for instance.

Leave a Comment

Your email address will not be published. Required fields are marked *