What is POCO and what is DTO in the .NET world?

Plain Old CLR Object or POCO is a play on the term POJO, from the Java programming world (which was coined by Martin Fowler in 2000) and is used by developers targeting the Common Language Runtime of the .NET Framework. POCO is a concept that has been the source of many misconceptions because of the similarity with the concept of DTO (Data Transfer Object).

POCO is a Business Object. It might have data, validation, and any other business logic that you might want to put in there. But there’s one thing a POCO does not have, and that’s what makes it a POCO. It doesn't not have persistence methods. If you have a POCO of type Person, you can’t have a Person.GetPersonById() method, or a Person.Save() method. POCOs contain only data and domain logic, no persistence logic of any kind. The term you’ll hear for this concept is Persistence Ignorance (PI). POCOs are Persistence Ignorant. The aim of POCO is to represent a domain (business) entity and to cut any other responsibilities, e.g. infrastructure concerns, that your domain objects shouldn't have.

The roots of the problem POCO tries to solve lay in past. With first versions of ORM technologies you weren't able to use POCO since it required the entities to inherit some base class from the framework itself. In case of Entity Framework, POCO wasn't possible in very first version and each entity was required to inherit Entity base class. This requirement created dependence of your data model on the persistence technology, which makes lots of things hard or impossible. Things like unit testing the model requires mocking Entity Framework behavior which proved to be practically impossible. You also cannot use the model with different persistence technology or you cannot use the model in different context, like in mobile environment. Having persistence embedded in your model objects simply violates the concept of separation of concerns.

DTO stands for Data Transfer Object. In fact, DTO is a very simple concept: Data Transfer Object is an object used to store data. And only to store data. That's all. There is no behavior (methods), only data fields or accessors and mutators which are just used to get and set data. The aim of DTO is to move data across layers of application: from Data Access Layer to Business Logic Layer. Usually, DTOs have fields of primitive data types only (int, string, bool, etc).

So, the sumary is: DTOs are simple data containers used for moving data between the layers of an application. POCOs are full fledged business objects with the one requirement that they are Persistence Ignorant (no get or save methods). Sometimes this concepts go hand in hand together: DTO might be a part of POCO as a field to store data. In some architectures it is otherwise: all business logic is separated from POCO into separate layer usually called Business Logic Layer, in this case what is left from POCO class became DTO.

Short answer

  • POCO is a Business Object. It might have data, validation, and any other business logic.
  • What POCO definitely can't have is a persistence logic in any form: no CRUD methods, which could tie it to any persistence technology.
  • DTO is a simple data container class, which is used to move data across application layers.