We have 50+ users in remote locations running our CSLA/SQL Server application with a local copy of SQL Server. A ton of work is done to get data moving from these clients back to the main head office SQL Server and back out again to other users.
I have (finally) convinced management that the internet is ubiquitous enough to get rid of the local SQL Server and require users to be interent/VPN connected to run my app. Hooray! This gets rid of all the data synchronization code, and all of the local SQL Server deployment (including backing up the master database and restoring it on 50+ laptops every year) .
The users have ONE request if we go this route - they want the ability to "check out" the data they are working on (which are already conveniently CSLA classes) and work on them in offline mode. The rest of the application except for this document editing would be available only while connected.
I figured I would just serialize the CSLA objects to disk somehow and this would be a piece of cake. After reading about serialization, though - maybe this might be harder than I thought.
The sample code below seems to work for saving to disk (and the similar load as well) - are there any "gotchas" I need to worry about, though? It sure sounds like there might be after reading the forum/FAQ. Is there a better serialization class to use?
Dim f As Csla.Serialization.BinaryFormatterWrapper
Dim p As PlayerProperties <--- CSLA class
p = PlayerProperties.GetObject(New Guid("CDA77E4B-46AC-11D5-9F36-0090273C1D4C"))
Using fs As New System.IO.FileStream("c:\temp.txt", IO.FileMode.Create)
f = New Csla.Serialization.BinaryFormatterWrapper
You should absolutely not use serialization for anything beyond transient data transfer.
Or to put it another way, if there is any chance of changing your assemblies while serialized data is floating around out there, then you shouldn't use serialization - because you may be unable to deserialize the data after you update your assemblies.
So serialization is great for over-the-network stuff - that's transient. It is often OK for caching, since you can just discard the cache if deserialization fails.
But it is not good for maintaining editable data over a period of time - unless your users are ok with just losing whatever they have taken offline in the case of an app update.
Personally, I would keep the local SQLServer (or MSDE) on the machine and store the offline data there. your objects already know how to talk to it, they just need a way to differentiate between offline and online. The Serialization issue goes away and you only have to change the Sync code into some sort of check-out/check-in code. With the proper thought, this could be very powerful.
To counter the app update issue, I would suggest that all offline data must check in before an app update could proceed.
Just a thought.
thanks for the feedback. I stumbled across the MobileFormatter, which requires me to implement a field-by-field read/write to the XML stream (assuming I don't have managed backing fields for everything, which I do not). Does this formatter suffer from the same "will break if new versions are deployed" problems as BinaryFormatter?
I suppose if I'm already doing field-by-field reading/writing, I can just create my own local file format and read/write to it, so not much difference.
As far as keeping MSDE on the local machine, that is probably an option, but I would save our machine deployment guys HOURS AND HOURS of work every year if I could get rid of it, which is one of the the primary reasons for pushing an "almost exclusive online app" type of architecture (the other reason would be getting rid of data synchronization efforts).
MobileFormatter is designed to provide comparable functionality to BinaryFormatter/NetDataContractSerializer without the need for reflection. It is the only serializer available for Silverlight or WP7. It may become the primary serializer for web apps in the future as well, partly because it can run in medium trust, and partly because it may be a practical way to do some interesting HTML5 json serialization (that's very speculative!!).
While you could maybe misuse MobileFormatter for your purpose, you'd never be able to move to Silverlight, because it wouldn't be actually doing what's necessary.
If you don't want to use a client-side SQL database your best bet is to use a pluggable DAL (options 2-4 from http://www.lhotka.net/cslanet/faq/DataFaq.ashx), and have a client-side DAL that maybe stores the data into XML files or something like that. If you use a DTO-based interface between your business objects and the DAL you'd be well on your way - by definition a DTO can be easily serialized into XML using DataContractSerializer. And the DCS has provisions for versioning the XML/DTO schema over time.
Maybe take a look at SqlLite or Sql CE 4 (beta), they are embedded databases that don't require configuration. It doesn't require maintenance like MSDE and it is still a reliable data store so you don't have to write your own methods to store/retrieve data.
Copyright (c) Marimer LLC