I’ve just read about the repository pattern in c#. It will provide an interchangeable layer for how the actual data is accessed. That’s great. However, consider the following:
I have an XmlPersonRepository which will fetch XML data from a file and return it as a c# object (Person.cs POCO). Now I want the physical source of the XML data to be interchangeable too. Originally, it comes from a file, but it can also come from a web server or from a resource string. How would I implement this in the most reusable way? I don’t want to write something like XmlPersonFromFileRepository and a XmlPersonFromWebRepository, because it would mean code duplication. It would duplicate the code for converting the raw XML data into a c# object, but this code stays the same, no matter if i fetch XML from a file or from a web service. So it’s redundant to have the conversion code in both classes.
So in a nutshell, I want to have two abstraction layers: One layer which fetches the psysical XML data from whatever source, and another layer which converts this data into c# objects. Both should be interchangeable.
How can I implement this? And please tell me if this is a good idea or not, am I on the right track?
Simple. You just worded it in your question.
You have two problems to solve:
To implement the first problem:
– IXmlDataGetter, an interface getting a single XML data from a source.
“XmlData” should be either a byte[] or a Stream (Because XML contains metadata with regards to the encoding of data, I think it should be kept at byte level) or be a DOM Tree (like XmlNode). You choose the solution that fits you best.
“XmlDataName” is the way you identify a your stored data. Data has a name, however complex it may be. It may be just the string “PERSON” and the integer 25, being the id. The name of the data for the person with ID 25 may be the pair (“PERSON”, 25).
This interface, can be implemented for DB:
This interface can also be implemented for a file:
Of course “ResultOfQuery” and “ContentsOfFile” are just names of things I leave it to you to solve. And for the Web, build your URL from your XmlDataName the same way.
Now. Second problem, converting XML to C# object. You may use an XMLDeserializer, or parse the data with an XMLReader and build your object explicitly. You just have to create a class that does te job and takes the appropriate strategy as a constructor parameter:
I won’t get into the philosophical questions of IoC/Dependency injection here, but this is the basic pattern. The class that does the conversion just does the conversion. All it needs to perform the use case from end to end gets “injected” from “above”.
You separated the responsibilities, now you’re free to get your XML data from a user copy/paste in a textbox if you wish.