main MVC project, where M of MVC was moved to Data Access Layer
Common misconception. The M
of MVC
has nothing to do with data, despite the many examples and tutorials that claim so.
M
is your ViewModel and should reside in your MVC project. The ViewModels you have in your BLL are actually to be named DataContracts or BusinessModels.
In your controller you have something comparable to this:
Get(id):
dataContract = _service.Get(id);
viewModel = Map(dataContract);
return viewModel
In your service, something like this:
Get(id):
dataModel = _dataAccess.Get(id);
dataContract = Map(dataModel);
return dataContract;
And in the DataAccess, you perform the proper joins according to the object requested. You are however of course free to add custom methods to your DataAccess when required, so your service can call those methods:
GetWithBars():
dataModels = _repository.Query("select from foos join bars");
return dataModels;
The main reason you would have the interfaces for your repositories in your BLL is to avoid having hard references to the separate DAL but instead have your changing DAL reference the stable BLL.
To be able to swap out implementations without changing the stable BLL
On the internet this might not be the main reason in general, but this would be a compelling reason for me to prefer option 2 in your situation.
Let's assume that you are using a DI (dependency injection) container. If you configure this using a configuration file, for example, you would tell the container that the implementations for the repository-interfaces in the BLL can be found in the DAL.Sql project. Once you switch over to a NoSQL solution you would create the DAL.NoSQL project, deploy it and change the DI container configuration to resolve the implementations of the repository from the new project. Your new DAL depends on the stable BLL that does not need to change.
However, if you go with option 1, you might not be able to hot-swap the DAL project. If you use .NET for example you could run into issues where the BLL project depends on a certain version of the DAL dll and you would not be able to swap out the DAL without changing the BLL as well.
Because the repository interface is part of the BLL
A repository is merely a gateway that defines how your application will retrieve data. In that sense it is as much a part of the business logic as your domain objects. The concrete implementations can change, but the interfaces themselves are part of your business logic.
Because it isolates the BLL
Having the interfaces and implementations in the DAL means bringing all of the DAL into the BLL. There is nothing preventing developers from using objects from the DAL project in ways that they shouldn't be used. Having the DAL depend on the BLL means the BLL can only contain the interfaces that it needs.
To avoid a separate project with the domain objects
Your DAL and BLL both depend on your domain objects. If your BLL has a class that uses a repository and a domain object, you cannot put your repository interfaces into the DAL as that creates a circular reference (BLL needs interface for repository in DAL, DAL needs domain objects in BLL). So you would have to split the BLL and the domain objects into two projects so your BLL can reference the domain and the DAL and the DAL can also reference the domain.
Best Answer
I think the business object/entities you are describing aren't actually domain objects in the DDD-sense, if you are applying DDD your business logic would be contained in the Domain Objects themselves; the entities you are describing (having business logic in a separate layer) seem to be Anemic.
If you want to know whether to use DDD you would have to establish whether or not the domain you are working in is sufficiently complex to involve Domain experts as "[f]undamentally, DDD is the principle that we should be focusing on the deep issues of the domain our users are engaged in, that the best part of our minds should be devoted to understanding that domain, and collaborating with experts in that domain to wrestle it into a conceptual form that we can use to build powerful, flexible software." Eric Evans
The fact that you are essentially displaying data from different tables on the basis of certain inputs and some logic would lead me to believe that your domain is not complex enough to warrant applying DDD.
In order to address your last concern, a common DDD architecture would not have the DAL and BLL link to the Domain Layer, the DAL would be abstracted behind a repository which would expose and persist your Domain objects; business logic would be contained in the Domain objects themselves, and your "BLL" would actually be a service or application layer that uses the repository for access to the domain objects, it is "a thin layer which coordinates the application activity. It does not contain business logic. It does not hold the state of the business objects, but it can hold the state of an application task progress". (from the book domain driven design quickly page 30)