C# – Business Logic Layer and Data Access layer: circular dependency

Architecturecdesign-patterns

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?

Best 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)
  Domain
    Business Entities
  Data
    Repository Interfaces
    **Your DataFactory**

OracleData (Project)
  Data
    Oracle Repository Implementations

SqlData (Project)
  Data
    Sql Repository Implementations

UI (Project)

Hope this helps.

Related Topic