Onion Layers

Onion Architecture with CsvMapper

I’ve been reading up on the Onion Architecture and think it’s a nice way of organising your code leading on to Domain Driven Design. This is my first project for this way of developing and it’s on the back end of a request from a good friend of mine to address a specific problem.

The Problem

Patrick who is the IT manager in a large GP Surgery in Oxford said they have a problem with getting Immunisations uploaded from their GP System (EMIS) to another system (Exeter). Currently this requires an export in EMIS to Excel then the manual editing of data to get it in the right format. This process ranges from simple mapping to looking up GPs Names and convert them to codes acceptable to  Exeter.

I said I’d help with what I call CsvMapper

CsvMapper

In a nutshell CsvMapper will take any csv file in any format and map it to another csv file in any format. The mapping data is maintained in a xml file which must have the same name as input csv file. I’ve developed a group of core “actions” which you hit the input field with to give your the appropriate output field. Currently the actions which are stackable are

<Map datatype =”String” id=”8″>
<Source ConnectTo=”6″ SourceId=”6″>
<![CDATA[As GMS]]>
</Source>
<Destination>
<![CDATA[MMR_UNDER_GMS]]>
</Destination>
<Process>
<Command action=”RegexAction”>
<Where><![CDATA[^True$]]></Where>
<Make><![CDATA[Y]]></Make>
</Command>
<Command action=”RegexAction”>
<Where><![CDATA[^False$]]></Where>
<Make><![CDATA[N]]></Make>
</Command>
</Process>
</Map>

Load (loads a csv file which maps one primary key to another eg GPName in the EMIS system to the GPCode name in Exeter)
QuarterStart (take the date today and returns the start of the previous quarter)
RegexAction (Replaces text with Regex expression)
RemoveSpaces (removes spaces from a text. In this example the Exeter system needs the NHS number without spaces)
SimpleMapping (passes the input to the output with no changes)

This is an example of a Map element. The above states that I’d like to map column no 6 in the input to column no 6 in the output with a heading of MMR_UNDER_GMS. If the value is “True” then convert to the text “Y” and if “False” then convert to “N”.

It’s open source under the GNU licence. You can find the source code at https://github.com/RazaToosy/CsvMapper

Domain Driven Design and Onion Architecture

I’m not going to talk about the theory of DDD. From my research here’s how I’ve implemented the theory into my application. There is more to it than this as DDD is more about adding layers to your code which define business problems rather than architectural or database design problems. Both DDD and Onion Architecture compliment each other.

The Onion Architecture is nice as in the older methods everything depended on the database layer. With the Onion Architecture the Domain Object and Interfaces are the Core of the Onion. Where the data is stored then becomes an infrastructure issue which is more on the periphery. I implement a Repository Pattern around data access. The project was too small to implement Entity Framework.

In the Onion Architecture you define a Core Assembly. This is a clean project and has no dependencies to other projects. In this project you define your Models, Interfaces and Services relating to the Core. You talk in Interfaces rather than actual objects to keep things loosely coupled. Here’s the Core in CsvMapper

Core

Beyond the Core are the Infrastructure and the UI Layers. Both depend on Core. Also UI has a reference to Infrastructure.

This is the Architecture View for CsvMapper

ArchitectureOverview

You talk in Interfaces or Classes Implementing Interfaces and only have one place where you instantiate the appropriate Class. I have a folder in the Infrastructure project which does this called Resolving Dependencies. In the UI class where the Click event starts the ball rolling I refer to this and only this. This way if in the future I create a Xls Mapper or want the Mapping to be located in a json file or some other format, this is the only place where I change the code as everything else is coded to interfaces.

Next learning step for me is IOC Containers which I’ve been told are Interface Factories on Steroids. Maybe for another Blog..

Factory Pattern

There is a nice Factory Pattern Implementation related to the actions. As CsvMapper loops through each input file and the Process Element has an action attribute, with reflection I create the appropriate object from the string name of this attribute return. This action object has to implement IActionable

//return the IActionable Object which takes
//the current Map, string and returns the
//result as a string.
IActionable process =factory.CreateInstance
(action.ProcessAction.ToLower());
theValue = process.Transform
(map, action, theValue);

It also uses WPF to create the form with rounded buttons. I wanted it also to be easily deployed so it doesn’t need an install file. I used LinqtoCsV to load the Csv but in hindsight was probably better off doing it myself as I wasn’t using any mapping features and then had to map the return to my own internal models. Nice library though. Finally it implements log4net to a log.txt file for error handling only.

Hope this helps others look at a simple implementation of Onion Architecture with a bit of DDD. Future enhancements would be to create a front end to manipulate the xml file so users and define mappings or even work out the mappings to generate the xml lookup file from an example csv input and output file.

CsvMapper at GitHub.

The latest build can be located here. Just upzip and place in a folder and run CsvMapper.UI.exe. Currently it’s in beta (0.9.0.0)

Photo credit: feesta / Foter / Creative Commons Attribution 2.0 Generic (CC BY 2.0)