Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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:

  1. Code a new set of entity classes to be used with NHibernate, because the entities we have were generated by LLBLGen.
  2. Create a new repository implementation that worked with the new entities + framework.
  3. 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.

share|improve this question
2  
I hate to throw a spanner in the works, but have you considered using a document database? I'm using one on my current project and it's not only the exact thing that I've been looking for, but it also answers every niggle I ever had with OR/Ms (and I had a million of those). –  Adrian Thompson Phillips Feb 27 '13 at 17:30
    
@AdrianThompsonPhillips - so basically NoSQL? My boss like SQL Server and Azure Table Storage. –  Jeff Feb 27 '13 at 17:35
    
Comments at downvoters are noise, and are to be removed. Please refrain from doing so in the future. –  casperOne Feb 27 '13 at 18:04
    
You seem to be really worried that the ORM/database provider are going to change, and perhaps regularly - is that a realistic concern? Why? –  Greg Smith Feb 27 '13 at 19:57
    
@GregSmith - Because the project I am starting, will very likely be reused & integrated somewhere else, that uses another database. Therefore I would love it if I could just reference my business & model projects, and plug in a new DAL repository. –  Jeff Feb 27 '13 at 20:00
add comment

migrated from stackoverflow.com Feb 27 '13 at 18:05

This question came from our site for professional and enthusiast programmers.

1 Answer

up vote 2 down vote accepted

Option 2 is certainly better in my view.

The models project carries all the entities and these are clean representations of your data in the application.

In your data layer project (which has a reference to your models project), you would implement repositories abstracted to interfaces, which return instances of your entities. The business layer then takes a dependency on these interfaces, and so has no interest in the implementation of the repo's or the ORM or the DB and is not impacted if those change.

You'll then have some kind of mapping to do, or what you're calling "Code First". That is, the mapping between the clean entities and the database tables. This mapping stuff could also live in your data layer project, and be swapped out per ORM/db provider.

Doing "Db First" or using code gen to make your entities is a neat trick, but in my experience creating a DB properly, application models properly, and mapping one to the other properly, is much more robust, less problematic, and doesn't take that much longer.

If portability across data sources, and keeping application entities clean (that is, they don't inherit from stuff, and don't have a crazy attribute count) are things you value - and you like massive speed and ease of use as well - have a look at Dapper. I've been using it successfully against SQL Server and Oracle for a long time, and can't recommend it highly enough.

share|improve this answer
    
This was the answer I was hoping to get! I will probably be using NHibernate for this, as it does exactly what I need, is pretty fast, easy to set up, and easy to map, but will definitely keep Dapper in mind! Thank you! –  Jeff Feb 27 '13 at 20:40
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.