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.
... 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.