4

We have a set of different POCO entities which represent the domain model for the application. Now we need to come up with an xml representation compiling data from different entities which is going to be consumed by some other application. We have a reference xml as to how the final representation should look like.

Based on the above, I have two questions which primarily are with respect to best practices and optimization:

  • Given a target xml structure, what is the best and recommended way to create an xml file based on data from different entities? Should i try to use xsl transform or generate target class based on xsd and use custom translations, etc.
  • Since this is a part of a POC exercise, the XML conversion would be finally replaced with data persistence in a database or/and transformation to JSON objects. I was wondering if I can use some design pattern to abstract out the target implementation so that the primary code will not get impacted when the xml generation routine gets replaced with a DAL call or JSON translation code. Any ideas?
koder
  • 887
  • 9
  • 29

2 Answers2

1

Create a target model (POCO-ish) based on the target xsd using the MS xsd tool and do a transform in code through a facade that hides the implementation of the translation.

To simplify the conversion you could use for example Automapper on github.

From the target model it would be easy to produce XML, JSON or persist the data using for example Entity Framework.

Example of genric JSON serialization:

    public static string GetString<T>(T value)
    {
        using (var ms = new MemoryStream())
        {
            var ser = new DataContractJsonSerializer(typeof(T));
            ser.WriteObject(ms, value);
            byte[] json = ms.ToArray();
            ms.Close();
            return Encoding.UTF8.GetString(json, 0, json.Length);
        }
    }

I've tried the XSLT route in the past and while it's powerful it has a tendency to get complex fast. With the target model above you will be able to debug your conversions should that be needed, it also offers you a range of opportunities for going forward.

Re: AutoMapper, in a case like this when the target structure is complex and possibly differ from the source it's hard to have AutoMapper map everything directly, I usually create an Orchestrator/SuperMapper that is responsible for the overall structure/mapping that uses AutoMapper internally.

Tip: If a target requires values from multiple it's possible to set it up as a sequence of mappings into the same object see this question/answer.

It's hard to give a good generic answer without specific structures in mind.

Re: Facade Wikipedia has a good definition of this pattern >> Facade on Wikipedia But in short define the simplest possible interface for your Orchestrator/SupperMapper so you separate the inner workings of translating the structure from the rest of your application. This way you can easily swap it for something else when your needs change. This way the rest of your app does not need to know about AutoMapper or the target model. All it knows is to put in the source model and expect to get Json back for example.

Community
  • 1
  • 1
Tommy Grovnes
  • 4,126
  • 2
  • 25
  • 40
  • 1
    The target object will need data from multiple domain entities. How can we do that with AutoMapper? Can you explain a little bit more about hiding a translation implementation using a facade. If you can provide some sample code, it would be easier to understand. – koder Jul 13 '12 at 14:02
0

The design pattern you are looking for here is a Data Transfer Object (DTO). These are simple classes that have no behaviour. You would then create an Assembler to convert from your application's Domain Model to the DTO.

The DTO can be easily created using xsd.exe assuming you are using C# or VB.Net. I am sure you can find an equivalent for other languages.

Once you have this set up, what you put inside the Assembler to do the conversion is a little less critical because it is nicely encapsulated. It can be easily changed in the future if you need it to. However as Tommy says I would advise against using XSLT. XSLT only really allows you to change the shape of an XML document, it does not easily allow things like substitution of values (enum names for ids), or calculations (sum of order lines to give a total).

For more information see:

http://martinfowler.com/eaaCatalog/dataTransferObject.html
http://msdn.microsoft.com/en-us/library/ms978717.aspx
http://en.wikipedia.org/wiki/Data_transfer_object

Martin Brown
  • 24,692
  • 14
  • 77
  • 122