The first version of the Entity Framework could create an entity data model by reverse engineering a database, and then generating code from the resulting conceptual data model. One of the enhancements in the second release of the framework was to make the code generation extensible through T4 templates. You could download a template provided by Microsoft, customize an existing template, or create a template from scratch to tweak the code generation strategy.
T4 templates provided a nice extensibility point for teams who wanted to change the generated code. Unfortunately, one of the templates provided by Microsoft was the “POCO Entity Generator”. The POCO Entity Generator came about because many people disliked the default code generation strategy. The default strategy forced all the entities to derive from an Entity Framework base class (EntityObject), and included a large number of partial methods and serialization attributes. Many developers asked for the Entity Framework to work with POCOs (plain old C# objects) instead – but why?
The word POCO came from the word POJO (plain old Java object), a term coined around the year 2000 to describe simple Java objects that were not encumbered by framework requirements. The Manning Book “POJOs In Action” is an interesting read about why POJOs came into existence. To summarize - programmers were frustrated trying to solve business problems because the application frameworks required boilerplate infrastructure code in every class. The boilerplate code was noisy, the components were difficult to test, the software was slow to build and deploy, and the overall architecture guided developers towards implementing procedural code and transaction scripts.
POJOs were about making object-oriented development easier, because a programmer didn’t have to think about business logic, persistence, and transactions all at once. POJOs let the developers drive the software design using business requirements instead of framework requirements. In short, POJOs let the developers control the code.
The Entity Framework POCO template technically generates plain old C# objects, because the objects don’t derive from a framework base class, and don’t include partial methods and serialization attributes. However, the true spirit of code ownership through POCOs is lost in code generation. The true spirit of POJO and POCO programming is in owning the code from the start and building a core model of the business problem to solve. Like a gardener who cares about seedlings – the developer wants to grow the classes with a hands-on approach. With EF 4, the code generator still owns the POCO classes, and the POCO template does not address one of the early criticisms against the Entity Framework expressed in the Entity Framework Vote Of No Confidence.
The Entity Framework encourages the Anemic Domain Model anti-pattern by discouraging the inclusion of business logic in the entity classes. While it is possible for the business logic to be written in partial classes, this adds some awkwardness to the code as the entity data and the entity business rules and logic live in separate knowledge and user experience contexts.
Using code generation to create a set of POCO objects is backwards, but I’ve met many teams and developers who feel good about using generated POCOs because the word “POCO” covers them in the amorphous blanket of software best practices. They don’t use test-driven development, hexagonal architectures, break away from procedural transaction scripts, or try to use any of the advantages true POCO development could provide.
The POCO template, by virtue of its name, tricked many developers into cargo cult programming.
This leads us to the lesson for this entry:
The developers who wanted to work with POCOs didn’t technically want POCOs – they wanted to own the code and build applications starting with an inner core of domain logic. Code generation couldn’t solve this problem, and the POCO template was a misleading solution.
In a future post, we’ll learn one last lesson from the evolution of the Entity Framework.