Business Logic Layer and Data Access layer: circular dependency


I’m having a little Architecture problem. In my project I have a Business Logic Layer (BLL) that contains all my business rules, models and OO API for the interface. Each object has static methods like getById that return an instance of said object. Each object also has methods like save and, delete. This is very straightforward OO code.

Now I have a DataAccess layer (DAL), contained in a separate namespace, for each BLL object I have a DataClass or “Repository” which executes the getById and save commands. So in a way, the BLL save and getById methods are a thin layer around the DataClass methods.

public static NewsItem GetByID(int id)
       return DataFactory.GetNewsItemRepository().GetNewsItemById(id);

In order for the DataClasses to return BLL objects, they need to know the BLL. so now we have:

GUI ---> BLL <---->DAL

The DataFactory only returns objects that implement an Interface, so I can hide implementation details like “OracleNewsItemRepository”.

But now for the thing that has been bugging me ever since I started Object Oriented programming. In my current solution, both BLL and the DAL need to know each other. This is a Circular Dependency, and it is best practice to avoid circular dependencies. Also I only want to expose the interfaces (and my DataFactory) and not my classes. This can be done by placing the DAL layer in a separate Assembly. Which would make sense. However, Visual Studio does not allow two Assemblies to refer eachother. Another question about this: C# internal access modifiers

Somehow I think I got my whole data access pattern wrong. It feels like I am convoluting the ActiveRecord pattern with other stuff like DataMappers. I have spent a lot of time on Martin Fowler’s site, but those patterns are described very generic and are illustrated by a very abstract UML diagram.

They don’t solve my problem. Maybe I’m a bit anal, and there is no such thing as a “perfect data access pattern”. And what I do now doesn’t seem terribly wrong. But how I do things now, seems off…

Any ideas?

5/23/2017 11:46:18 AM

Accepted Answer

I think your data access pattern is fine. What you are not doing is coupling your BLL to the OracleDAL. You are coupling to the DAL interfaces. A certain bit of coupling is absolutely required or you could never get anything done.

I assume that your DataFactory and the INewsItemRepository classes exist outside your DAL Layer. The following is an example of how my solutions are organized. I don't use ActiveRecord, so this may not suit you perfectly.

Core (Project)
    Business Entities
    Repository Interfaces
    **Your DataFactory**

OracleData (Project)
    Oracle Repository Implementations

SqlData (Project)
    Sql Repository Implementations

UI (Project)

Hope this helps.

1/19/2009 6:17:18 PM

In my opinion:

The Data Access Layer (DAL) should operate on POCOs (Plain old CLR objects) using operations such as: SaveNewsItem ( NewsItemDAO newsItemDAO ). The POCOs are your DAOs (Data Access Objects).

The Business Layer should contain the logic to convert a Data Access Object (DAO) into a rich business object, which is probably just the DAO plus some operations as well as any decoration/enrichment.

The DAL should have no knowledge at all about the Business Logic Layer. It should, in theory, be able to be called from any client. For example, what if you wanted to seperate the DAL from the application and deploy it as a seperate service exposing itself via WCF?

As mentioned, the DAL operations, e.g. SaveNewsItem should be be accessed by the BO via interfaces, perhaps via dependency injection/IoC.

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow