I am starting a new project, and I want to follow the separation of concerns pattern, and I have been reading on the topic, and now I am in doubt of how I should go about this.
Here is how I thought I should go about it:
- Application/Presentation Layer uses the Business Layer. Works with the entity interfaces.
- The Business Layer uses the Data Access Layer (repositories, models/entities). Works with the entity interfaces.
- The Data Access layer works with the Database, and is using an OR/M solution - the solution itself may change. Works with the entity implementations, but returns interfaces to the business layer.
The business layer would get a specific repository implementation injected. The repository would return entities in the form of Interfaces, so the business layer would not care what kind of OR/M we use. If we decided to switch from using e.g LLBLGen to NHibernate, we would do the following:
- Code a new set of entity classes to be used with NHibernate, because the entities we have were generated by LLBLGen.
- Create a new repository implementation that worked with the new entities + framework.
- Switch out the repository implementation being injected into the business layer with the new one - the repository works with interfaces, so business layer could remain unchanged.
The main point of interest (pain) here, apart from having to modify the generated entities to implement our model interfaces, is that we have to create entirely new entities just because we are switching frameworks. The same would be necessary if we switched out the datasource to something the OR/M didn't support.
This is the way I've been doing it (because hey, auto-generating your entities is how you get all the ladies, right?), but then I came across this excellent article!
Here is how I think I should go about it now
- Entities are stored in a separate namespace/project -
MyProject.Model
- Application/Presentation Layer uses the entities in
MyProject.Model
to display stuff. Uses Business Layer to retrieve/save them. - Business Layer also uses entities in
MyProject.Model
. Uses a repository from Data Access Layer that gets injected, depending on what OR/M we are using - Data Access Layer uses the OR/M frameworks with code-first, so we can work with
MyProject.Model
regardless of what OR/M, or even Data Source we are using.
Pro's and con's for solution 1:
- Pro: Can use Database-First to auto-generate entities. Timesaver!
- Pro: Works with interfaces for entities
- Con: Works with interfaces for entities (this may be too much abstraction?)
- Con: Have to use an entirely new set of entities to implement a new OR/M or Data Source. They need to be modified to conform to my interfaces, chances are they can't because of how they do relationship-management.
Pro's and con's for solution 2:
- Pro: Write entities/models once, use for any DAL implementation
- Pro: No need to use interfaces for entities
- Con/Pro: Stuck with code-first for every OR/M. On the other hand, gives you full-flex on how you want them to look.
- Con: Some framework (e.g EF) are simply easier to get rolling with when using DB First.
I had more pros and cons before, but I lost them again..
Conclusion: What solution would you pick, and why? Or do you have an even better solution?
Please don't close as "not a question", because I really need an answer. Thank you.