Search code examples
model-view-controllerarchitecturedomain-driven-designrepository-patternbusiness-logic-layer

Circular dependency of Business logic and Data access layer


I am working on MVC project where I am following the layered architecture. After reading and researching on the web, I figured out that having seperate layers is optimal approach. So, my layers are:

  • Presentation layer has: Controllers, Views
  • Business Layer: Separate class library project (Includes domain models(Representing table entities), business logic services, separate folder for ViewModels)
  • Data Access Layer: Has calls to the database (SQL statements, connections)

Now, the problem arises :

BLL calls to Data access layer :

    public PartnerOperation(IDataAccess dataRepository)
    {
        _dataAccess = dataRepository;
    }

    public void InsertRequest(PartnerRequestModel partnerRequestModel)
    {
      _dataAccess.InsertIntoDB(partnerRequestModel); //Domain object passed to DLL method
    }

Now, my BLL is depending on Data access layer which is depending on BLL because domain objects are inside BLL. So, both are having reference to each other.

I am rigorously searching on it for couple of weeks, but couldn't find a way out.

I have already gone through Business Logic Layer and Data Access layer: circular dependency but it doesn't address my problem completely.

Some websites support layer architecture, some claimed Onion Approach is better. For instance: this article claims that this whole approach (Controller -> BLL ->DLL) is not optimal.

  1. How can I overcome the circular dependency?
  2. Is my approach toward building this Web Application valid?

Solution

  • You could use an Onion Architecture, also known as Hexagonal or Ports & Adapters (slightly different variations on the same thing).

    With this architecture, your persistence (data) layer references your domain layer, so your repositories, etc. can return domain entities. In order to use your repositories from your domain layer, you then need to place the interfaces for your repositories in your domain layer and wire them up to the implementations (in the persistence layer) using an IoC container.

    Edit

    It doesn't sound as though you're doing DDD from your terminology and the code sample you've provided, I'm guessing you've included the DDD tag because of the term repository, so I'll proceed using non DDD, n-tier and layered terminology.

    You'll be looking at a call stack pretty much the same. It'll be Controller -> Service -> Repository. Ideally you need to be referencing a 'Unit of Work' in your service and not referencing the repositories directly.

    The only difference is the project references, instead of the BLL referencing the DLL, it'll be the other way round. Your controller will still call code in a service in the BLL. It's just that your BLL service won't have a reference to the DLL. So to get round this, you put the interfaces from the DLL repositories in the BLL and wire them up using an IoC container like Ninject or Castle Windsor.

    You might need to look into a few other topics like Dependency Inject (DI) (passing dependencies in through the constructor), Inversion of Control (IoC) (a big global mapping of automatic instantiation of configured concrete types of interfaces) and for a longer term goal maybe domain-driven design (DDD) to make sense of some of the advantages you'd get from using an Onion Architecture.