views:

616

answers:

3

Hello: I'm trying to get a clear final answer to a question that's driven me nuts for a long time.

It's commonly expressed that BLL should contain Business Logic and Business Objects (BO), and have a reference to the DAL. The DAL on the other hand, cannot have a reference to the BLL, so it cannot accept the BO's as arguments, or return the BO's as return values.

The most traditional answer to this problem is to:

a) Accept simple parameters, and return (preferably Typed) DataSets and DataTables to return data: namespace DAL { public class Contacts public DataTable GetContacts(){...} public UpdateContacts (DataTable contacts) {...}

b) The second most recommended solution is to define temporary, serializable, Data Transfer Objects (DTOs) (sometimes called Value Objects (VO)) which have only fields and properties, no methods, and are only used to briefly transfer the data back up to the BLL layer, where there are used to populate new BO's, at which point they are then discarded.

c) Use a common third assembly (eg called Entities.dll), that define the BO's, and is referenced by all 3 layers: the UI, BLL, and DAL.

Option a) takes the least work to implement (no need to build another assembly), hence why so often proposed, but DataTables have extra wiring that doesn't need to be needed just for the simple operations.

Yet it's very unclear as to which of b) or c) is better...

I see b) offered sometimes, and almost never c), although c) seems to be the easiest of the two.

What am I missing? Why is c) so rarely offered even though it appears to be logically the easiest, and why is a) offered when its clearly not suitable for all scenarios (eg returning single objects)?

Thank you!

+1  A: 

Well, I hardly see (b) employed in practice. I use the approach described in (c) most of the times (the other times is when I don't even separate between the BLL/DAL or have a domain model at all). After all, the business and data components are usually physically co-located, so it's straightforward for the BO to be shared by these two. In fact, frameworks like Hibernate, Entity Framework, Linq2Sql etc. actually encourages (c) by allowing one to perform ORM for complex domain model.

DTO is more typically used to pass data from the BLL to the UI though, esp. when the UI and BLL are deployed in separate servers. In this case, the UI will likely need a simplified view of the domain model to reduce cross-process roundtrips and minimize impact of change (when the the domain model changes).

Buu Nguyen
A: 

ADDENDUM to original Question:

I think (after the first response, by Buu Nguyenthat the following Reference pattern is perfectly acceptable, and maybe even recommended with LINQ, etc:

BLL > 

 v    Business Entities Layer (BEL)

DAL >

Unless BLL and DAL are on different tiers, and BLL communicates to DAL via WCF...? In which case it won't work (the Business Entities returned by DAL via WCF will be serialized, and and on the BLL side will be deserialized into Proxies of the original BE's...and not mapped back to BE's themselves. Or is that patently wrong, and the above reference pattern will work for when BLL and DAL are in same tier, as well as in different tiers?

ADDENDUM #2: Found an interesting link as to why its actually good to use an external assembly for the BO's. He states that "It is a violation of the rule that the layer should only know about the layer immediatly below, but the database which dictates the column names is not directly below BLL it is below DAL. So not typed DataSets do not shield you from the database and that is why I think they are wrong. A better solution would be to use a strongly typed objects defined in a separate project. So for example there will be a Teacher class in the DTO with a Name property but without a Grade method."

A: 

I wouldn't be surprised if (c) was quite common. And if your BLL and UI are on a different server you can also pass entities over the wire if you are using WCF. Take a look at this example for how to do serialization of entities here [zip] and here's a link to the downloads page. This post might also help with serializing with WCF

Jonathan Parker
HI Jonathan: the first link requires authorization. As for the second link, which one were you refering to -- the Interfaces or Data Services example?
Sorry, I've added permissions now so you should be able to download it via the link above. It's called "DDD and WCF - Serializing Entities".
Jonathan Parker
Hi Jonathan:Thanks for the links.Conclusions:a) DTO's can be serialized/deserialized to the same object, if both Tiers have ref to the same BO/BEntities assembly:DAL <- BO#1 v (using WCF)BLL <- BO#2ie: external BO.dll solves most problems.b) why prefer typed DataSets to custom DTO?
I think you're confused. Or maybe I am. What I'm proposing is c) which is no DTOs and no DataSets just BO (business objects). These BOs can be hydrated by the DAL serialized and then referenced directly by the UI. This is how CSLA.NET works. The benefit: logic and validation are kept in one place.
Jonathan Parker