Object Encapsulation With EntityFramework
One of the four fundamentals of Object-Oriented Programing is Encapsulation which is defined as: “A language mechanism for restricting access to some of the object’s components”. This would help us separate the internal implementation from the publicly accessible surface of the object. The idea is to hide how the object actually work from the outside world, so that we can change the internal without breaking anything as the object still looks the same from the outside.
Sometimes we just ignore this and expose the object’s internal, this is true specially when we come up with a limitation such as serialization and persistence in the frameworks that we use.
Entity Framework as of version six, has some limitations that can be worked around, in this post, I’ll give you some hints on how to apply encapsulation and information hiding on your domain objects, while letting EntityFramework do its work.
Object Construction
EntityFramework needs a parameterless constructor to construct an object when it needs to instantiate the object before hydrating the object. You might think that you need a public parameterless constructor (a.k.a nullary constructor) but that’s not true. You can get away with private constructor. This helps with encapsulation as the object can only be constructed by user of the code (e.g. your application) correctly.
1 | public class Product |
As you can see from the code, there’s no way you can create an invalid Product object. This class works perfectly fine in EntityFramework as well.
Collection Mapping
Your domain entities might have collection that need persistence, but when you expose your collection as IList or ICollection, entries can be added directly from the outside world to the collection. Although you can enforce proper construction of the object by using the right constructors, this still doesn’t make it right.
Let’s take the above Product class as an example. If you want to keep history of the name changes, how would you do that? Here’s one way of doing that:
1 | public class Product |
Although encapsulation and OO design practices in general are key, there’s more than just that when it comes to properly designing a domain. Since this is more a DDD topic, I’ll keep it for another post.