Question

I am in the starting phase of a new project. Since, I always want to improve myself and try to avoid the mistakes from the past (everyone has some baggage), i looked at the Layered Architecture Sample for .NET. Looking at the data and business logic i spotted that it the data layer actually has a reference to the ExpenseSample.Business.Entities assembly, so the data layer is aware that there is business layer. That looks and feels kinda awkward.

Sure, it saves time mapping DataObject to BusinessEntities, but isn't a "dangerous" approach?

Looking forward to some discussion and maybe some better solutions.

UPDATE: Thanks for the input. I now use

MyApp.Data.Contracts.*
MyApp.Data.Access.*         /* has the classes to access the DB and maps it to 
                               the Data.Contracts */
MyApp.Business.Entities.*
MyApp.Business.Components.* /* accesses the classes from Data.Access, 
                               maps the Contracts to the Business.Entities and 
                               provides the components to access them */

So this way i can make sure that internal changes to the representation of my data do not effect outer layers.

Was it helpful?

Solution

... so the data layer is aware that there is business layer

Not quite correct, it's just aware that there's a namespace called Business.Entities, but these entities are certainly leafs in the architecture. They depend on nothing else, but the .Net framework. The entities don't actually have any logic in them (apart from a ToString()) so they're just acting as data contracts over the whole architecture. Also they're free from references to any other projects. Only thing that doesn't make them POCOs is that they're serialization-aware.

As Baboon mentioned, this approach is possible and I'm sure there are examples where this works very well. And if you look at the project and the code it all looks so nice and cozy I just want to fall in love with it.

And it will be nice and orderly as long as you carefully plan every addition to your whole architecture, review every change and have tight communication with the developers. But as soon as your architecture, your database and your business processes evolve in a more rapid fashion, you'll have to stretch far to model the data for all those layers with common objects. There are some examples that in my opinion speak in favor for layer-specific data contracts. Among them is that some day the UI programmer wants to have PropertyChanged notifiers in your objects for his UI layer. Hrmpf! You can't do that without also affecting your BAL and DAL. Another day you come across the case that you want to have GUI-only properties stored in the entities (like display color, position on the screen, selection states, etc.). What's the database got to do with it? And if you looked carefully you have noticed that the entities already have layer-specific treatments. Did you see the virtual keywords on the navigation properties? They're there so that EF can subclass them and give you lazy-loading enabled proxy classes... which in turn are likely not meant to be transmitted over the service.

The alternative is to use object mapping (either manual, through templates or by libraries such as AutoMapper). This solution is certainly less clean, less cozy, as there's code duplication, and lines and lines of mapping code. But all that allows you to decouple the data in your layers and model it according to the specific needs for each layer.

OTHER TIPS

I disagree, some objects need to be accessed by all the layers, i do it like this:

-----------
| DAL | E  |
------- N  |
| BAL | T  |
------- I  |
|  G  | T  |
|  U  | I  |
|  I  | E  |
|     | S  |
-----------

The DAL is usually connected to a WCF service, and shields the rest of the application of knowing it (so it can be changed in a few years when WCF is outdated).

The BAL is mainly specific to the application (although could be reused in another app), but the entities are made specifically for the application, it's highly unlikely that i would ever use them somewhere else.

Of course, that's for a reasonably small app, it can be extended with other dlls (modules, third party, etc) and get much more complex, but that's the idea.

I guess what i'm trying to say is Entities and BAL are two different things, don't mix them up ;)

A general rule is that the lower layer should have no knowledge about the upper layers. The example is incorrect since the Business Entities is part of the BAL and not the DAL. Hence the business layer should do the mapping and not the data layer.

Mapping doesn't really take time, just use something like ValueInjecter

Disclaimer: I've not looked at the linked sample. Just giving my two cents about layering in general.

One thing I would say is that if you are going to allow the DAL to access business objects then you may as well create one project and separate BAL and DAL into separate directories and namespaces within that project. At least you're not kidding yourself about the layering then.

On most projects I've worked on there has been little benefit in separating BAL and DAL into separate assemblies. If your database solution is likely to change, and you want to future-proof yourself, then use an ORM like nHibernate instead.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top