I write this post in order to get some feedback regarding what I currently think about EF 4.1 Data Annotations and how it fits in DDD Architectural styles.
About DDD Architectural styles, here it is our Architecture Guide (Though we are actually writing its second edition, adding EF 4.1 Code-First approach). But most DDD Architectural concepts and patterns are exposed there:
The subject I want to toss about is the following:
In DDD architecture designs we must isolate our Domain Model Layer and therefore, our Domain Entities from any other layer, especially from infrastructure layers, like Data Persistence layers where we have the selected data technology (like EF or NHibernate, etc.). Even more, our Domain Classes (Entities, Value-Objects, Domain Services, etc.) should comply the PERSISTENCE IGNORANCE PRINCIPLE. This is why POCO Entities are the right choice for DDD.
Ok, then here we come with EF 4.1 CODE-FIRST approach, which is great for POCO Domain entities and fits great within DDD Architectural styles. Cool!
If you deep-dive a bit into EF 4.1 CODE-FIRST, you’ll see that the initial way to make the mappings from your POCO Domain Entities classes towards your final database tables is based on conventions. Ok, that is nice, but then, if those conventions are not ok for you (because you need to adjust to an existing database or whatever), then you need to customize those conventions. You can do that either in two ways:
- Data Annotations. For any of you that might not know what is EF 4.1 ‘Data Annotations’, here you have a link:
- Fluent API. Regarding EF 4.1 ‘Data Annotations’, here you have another link:
What I think is the following:
‘Data Annotations’ might initially look very appealing and easy to use when decorating our classes with attributes, but, on the other hand, and from a POCO point of view, it is a bit intrusive on our Domain entities, as we need to write specific attributes which are links to a specific persistence infrastructure, like EF 4.1. Even when most EF ‘Data Annotation’ attributes are defined within the ‘System.ComponentModel.DataAnnotations’ namespace which is part of the .NET Framework, still it is a bit intrusive on our Domain Entities.
On the other hand, using ‘Default Conventions’ or customizing it with ‘Fluent API’ is a way that fits much better with the PI (Persistence Ignorant), because our Domain Model will be ignorant of those mappings which will be defined into our Data Persistence Infrastructure layer, so, our Domain Model Layer will be better isolated from infrastructure implementation.
Therefore, if you are starting your project from scratch, the best way to go would probably be this: “Base your entity classes on default conventions, as much as you can”, because then your POCO domain entities will be cleaner, pure POCO!. Additionally, using ‘Fluent API’ would be transparent towards your Domain Entity Classes and you won’t stain your POCO Domain Entities, either.
We should make use of the Code First ‘Fluent API’ in order to change/customize our entity mappings, however, it must be written overriding DbContext methods (within our EF Context class). Specifically, we must override the ‘DbContext OnModelCreating()’ method. Therefore, that is part of the Data Persistence Infrastructure Layer, so we won’t be messing on our POCO Domain Entities.