It is a really bad idea to use the BinaryFormatter for long-term storage, because it is version sensitive. Upgrading your business DLL could render all your data unreadable.
In .NET 2.0 Microsoft did add some better versioning tools for the BinaryFormatter, so it is technically possible now to overcome those issues, but I still don't think I would recommend it as an approach.
I think the use of DTOs with the XmlSerializer is pretty good.
Better yet, use the WCF DataContractSerializer, and the consturctor overload that tells it to preserve the shape of your object graph. The one serious problem with the XmlSerializer and the default mode of the DataContractSerializer is that they don't preserve the shape of your object graph on deserialization, and this can be problematic.
The issue occurs when object P references C1 and C2, but C1 also references C2. (or any other double-reference scenario you care to name). If you look at the serialized XML you'll find the data for C2 in the byte stream twice, once for each reference.
When you deserialize the XML, you'll get P referencing C1 and C2, and C1 referencing C3 (which has the same data as C2). Oops!
DataContractSerializer, as I noted, has a constructor overload where you can tell it to preserve the shape of the object graph, so deserialization results in only C2 as you'd expect.
Perhaps some reason why you don't want to use a db? Db4o is hard to beat when it comes to just persisting an object (with graph), but it's not free for commercial use. Also there is SQL mobile edition.
Is it cost or the need for something embedded for staying away from a db of some sort?
We needed a local data store for a smart client so it could go offline, we choose to implement our own custom xmlserializer to keep the fidelity the normal on would not. Starting to consider a real embedded db though as any kind of serious query of those persisted objects becomes more and more difficult.
I don't really get the multiple inheritance for DTO's, at that point why wouldn't your one object be the CSLA business object and DTO with no need for inheritance. This would not be the CSLA way though, I know where your coming from, but with UI,XxxInfo,DTO's there is going lots of synching going on with schema change.
Justin
I think your missing the point of an object db like db4o, it isn't some relational db that you have decompose your objects into tables for, you literally persist in one "chunk" just like saving a file except its an object not a file so there is no translation of your object to a file repsentation(visible to you anyway).
Here is the code from thier online tutorial (http://www.db4o.com/about/productinformation/resources/db4o-6.3-tutorial-net.pdf):
Pilot pilot1 = new Pilot("Michael Schumacher", 100);
db.Set(pilot1);
does it get any simpler than that?
Granted using .Nets serialization isn't all more that complicated, but you can't query those objects once thier serialized.
I am with you on the DTO issue and sychronized schema maintenence, but you will not find alot agreement here on that. Rocky makes some very valid points about why DTO's should be used and how CSLA objects should defined by "behaivor" not data schema. But I am a believer that it is possible to have as Rocky says "One object to rule them all." and eliminate many of the redundant schema definitions that add to change overhead.
Justin
You can make the DTOs map a couple different ways.
The best way (imo) to think about DTOs in your context is to
view them as the result sets of stored procedures. In that view, they are
defined more by the data storage environment than by the shape of your business
objects. Then your DataPortal_XYZ methods are still responsible for mapping –
just from DTOs rather than ADO.NET.
The challenges of things like db4o or other ODBMS systems have
been discussed on this forum before. The big issue is that data is
relational. By its very nature it is relational. If you don’t treat
it relationally, you end up with duplicated, unsynchronized data fields all
over the place.
So if your data must be relational, and your objects are
directly defined by the database, then your objects are, by definition, relational.
In essence, they are entity objects, which are a very different concept
from business objects.
In fact, those entity objects are typically DTOs.
And so we come full-circle. You can define a set of
relationally-modeled DTOs and store them in files, in an ODBMS or wherever.
Doesn’t matter really, from a CSLA perspective, because your DataPortal_XYZ
methods will get the DTOs and pull out the data required by that specific
business object so it can fulfill its responsibility.
It is true that you can use CSLA to create data-centric apps.
And that often works quite well – people do this all the time.
But it is my view that you will be happier in the long run if
your business objects are defined based on responsibility and behavior. They
can then use data-centric entity/DTO objects in the DataPortal_XYZ methods, to
fetch and save data – no problem.
This is the future (potentially) thanks to the impending arrival
of LINQ for SQL and the ADO.NET Entity Framework: both of which follow this
exact model to sit behind CSLA .NET business objects. And, realistically, this
is the model used by anyone calling web services as a data layer behind their
objects, because web services provide and consume DTOs (and so do WCF services
by default).
Rocky
From: dagware
[mailto:cslanet@lhotka.net]
Sent: Monday, July 23, 2007 12:06 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Csla 3.0 Business Object only for persisting to
disk
Justin-
You are correct, I missed the point of db4o. It looks promising -- thanks for
pointing it out! I'll look into it further.
WRT BO schemas vs. DB schemas, I pretty-much agree with Rocky on this one. But
I don't see how that relates to the DTO issue, since if I'm not mistaken, the
DTO fields should map directly to the fields in the BO that are going to be
persisted, regardless of what the DB schema looks like. So you're always going
to have the fields defined twice, when you use DTO.
Still, I understand your points and appreciate them!
Rocky - Thanks for the explanation.
-Dan
An object graph is just a group of objects that reference each
other.
In CSLA the only supported shape (with the existing base classes)
is a parent-child-granchild-… shape.
But an object graph can really take any shape. A tree, a circular
linked list, a true “graph” (multi-connected arbitrary nodes), etc.
Rocky
I concur binary formatter for simple serialization, although technically storing in a file system is a type of heirchal db, but I assume you meant no relational db.
www.db4o.com is always an option, but its a db uh oh.
Also writing your own xmlserializer is not that difficult if the built in one does not suffice.
Justin
Copyright (c) Marimer LLC