Just writing about a requirement I had at work recently and I how went about implementing a solution for it utilizing CSLA and XML Serialization. I'm sharing this because I'm sure that others have come across a need to implement a solution comparable to this, and would like to share how I went about implementing it.
The project that I am involved with entails the automation of file processing. These files are sent to us in the form of .txt, .mdb, and .xls formats, and contain transaction information from companies such as UPS, Enterprise, Chase, etc.
For the most part, these files have much in common, such as transaction detail (transaction amount, transaction date, etc.). And for this information, I developed a class that really encompasses what a transaction is and the data that it contains. The class (Transaction : BusinessBase) is then populated by the parsing engine. When the Transaction object is saved, it is persisted to a Transaction table, containing all the columns.
But each source contains data unique to each company as well. For example, UPS files contain shipper and receiver information. Within our system, we don't really do much with this information (we're mostly concerned with the transaction data), but it's certainly data that we need for reference on occasion.
So because we deal with so many file sources, we decided to create a class abstraction called TransactionDetail, which is exposed by the Transaction class. Then for each file source, we create a concrete TransactionDetail class that exposes properties unique to the company data.
So, for example, UPSTransactionDetail -> TransactionDetail, and contains information about the sender, their address information, the receiver and their address information, etc.
To create a table to support each one of these concrete types would be absurd, and a solution that entailed one table that housed ALL fields relevant to ALL company file sources would be a querying nightmare.
So I thought I would take advantage of XML Serialization and SQL Server XPath support for querying. This is actually old hat, I've been serializing/deserializing objects to and from databases (both in binary and xml format) and have also seen others doing this for ages.
The way I went about this was to create one concrete detail class for each source, which was a POCO object, exposing public setters and getters for all properties.
Here is an example of how a concrete class is used:
UPSTransactionDetail detail = new UPSTransactionDetail();
detail.Address.Street1 = "123 Mill St.";
Transaction.TransactionDetail = detail;
Transaction.Amount = 45.45;
On DataPortal Insert/Update, the transaction saves its members to the Transaction table, and for the TransactionDetail member, it is serialized as XML to a field in the Transaction table.
This works great, and on the Fetch() of a Transaction, the TransactionDetail XML is reinflated as the concrete instance and can be used. Until.... You pass the Transaction object to a Silverlight client. When attempting to do this, you will receive an exception requesting you use the KnownType attribute.
So to get around this problem, I attempted to have each concrete type (and its subtypes, such as Address (which is another class)) to inherit from MobileObject. But between fighting with more KnownType exceptions and just having classes that weren't being populated on the Silverlight side, I went for another approach.
What I tried next was to have each concrete detail class inherit from BusinessBase and use propertyInfos. However, XML serialization failed outright because of something to do with the Rules stuff.
So finally, I decided to try having the concrete detail classes inherit from ReadOnlyBase, and using LoadProperty to set its properties.
While not a perfect solution, I was able to achieve what I was after, which was:
1.) Avoiding the creation and maintenance of numerous tables specific to sources.
2.) Serialize TransactionDetail as XML, and use SQL Server functionality to query the objects in the Detail column of the Transaction table.
3.) Deflate the XML as objects to use within a .NET application.
4.) Pass the deflated objects (and their deflated subtypes) back to a Silverlight client.
Hope this helps someone out there experiencing a similar need!
Copyright (c) Marimer LLC