436

POCO = Plain Old CLR (or better: Class) Object

DTO = Data Transfer Object

In this post there is a difference, but frankly most of the blogs I read describe POCO in the way DTO is defined: DTOs are simple data containers used for moving data between the layers of an application.

Are POCO and DTO the same thing?

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Patrick Peters
  • 9,456
  • 7
  • 57
  • 106
  • 5
    "POCO = Plain Old CLR (or better: Class) Object". Thus, objects of this nature in VB.NET would be POCOs too, not POVOs. – J. Polfer Jun 19 '13 at 21:06

10 Answers10

595

A POCO follows the rules of OOP. It should (but doesn't have to) have state and behavior. POCO comes from POJO, coined by Martin Fowler [anecdote here]. He used the term POJO as a way to make it more sexy to reject the framework heavy EJB implementations. POCO should be used in the same context in .Net. Don't let frameworks dictate your object's design.

A DTO's only purpose is to transfer state, and should have no behavior. See Martin Fowler's explanation of a DTO for an example of the use of this pattern.

Here's the difference: POCO describes an approach to programming (good old fashioned object oriented programming), where DTO is a pattern that is used to "transfer data" using objects.

While you can treat POCOs like DTOs, you run the risk of creating an anemic domain model if you do so. Additionally, there's a mismatch in structure, since DTOs should be designed to transfer data, not to represent the true structure of the business domain. The result of this is that DTOs tend to be more flat than your actual domain.

In a domain of any reasonable complexity, you're almost always better off creating separate domain POCOs and translating them to DTOs. DDD (domain driven design) defines the anti-corruption layer (another link here, but best thing to do is buy the book), which is a good structure that makes the segregation clear.

Michael Meadows
  • 27,796
  • 4
  • 47
  • 63
  • I know I referenced Martin Fowler a lot here, but he coined the term POJO, and wrote the book PoEAA that is the definitive reference for DTO. – Michael Meadows Apr 07 '09 at 14:57
  • I'm not sure if a DTO should not have behaviors.Judging by Martin Fowler's diagram ,DTO could have behaviors. – Beatles1692 May 26 '09 at 21:04
  • 41
    @Beatles1692, the methods depicted are serialization code. It's probably too broad of a statement to say "no behavior." How about "no business logic." Serialization code, and low level object stuff like hash code, equality, and tostring should be acceptable. – Michael Meadows May 27 '09 at 14:00
  • I also found a nice Assembly pattern from Microsoft to decouple DTO and business objects(POCO): http://msdn.microsoft.com/en-us/library/ms978717.aspx – Patrick Peters Mar 08 '12 at 10:58
  • don't even call them DTOs. They're called Models. DTOs are stupid terms to put on these. – PositiveGuy Mar 05 '15 at 06:06
  • @MSSucks in MVC Models often hold business logic so the term "DTO" is less likely to be interpreted differently – KCD Aug 03 '16 at 01:12
  • 2
    @PositiveGuy A model serves a different purpose from a DTO. DTO should be for transferring data from one domain to another (whether or not they're in the same runtime is irrelevant). A model "represents" an aspect of a domain, like a screen, service, or data source. Models include state and behavior, that are representative of what they're modeling. – Michael Meadows Mar 17 '17 at 16:43
  • 4
    Please note that anemic domain models are not necessarily bad, especially if your app is mostly CRUD. Favor simplicity over Martin Fowler. – Mariusz Jamro Aug 23 '18 at 09:59
55

It's probably redundant for me to contribute since I already stated my position in my blog article, but the final paragraph of that article kind of sums things up:

So, in conclusion, learn to love the POCO, and make sure you don’t spread any misinformation about it being the same thing as a DTO. 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). Lastly, if you haven’t checked out Jimmy Nilsson’s book yet, pick it up from your local university stacks. It has examples in C# and it’s a great read.

BTW, Patrick I read the POCO as a Lifestyle article, and I completely agree, that is a fantastic article. It's actually a section from the Jimmy Nilsson book that I recommended. I had no idea that it was available online. His book really is the best source of information I've found on POCO / DTO / Repository / and other DDD development practices.

  • 5
    Link to blog article: http://rlacovara.blogspot.com/2009/03/what-is-difference-between-dto-and-poco.html – Jamie Ide Aug 07 '10 at 12:49
28

POCO is simply an object that does not take a dependency on an external framework. It is PLAIN.

Whether a POCO has behaviour or not it's immaterial.

A DTO may be POCO as may a domain object (which would typically be rich in behaviour).

Typically DTOs are more likely to take dependencies on external frameworks (eg. attributes) for serialisation purposes as typically they exit at the boundary of a system.

In typical Onion style architectures (often used within a broadly DDD approach) the domain layer is placed at the centre and so its objects should not, at this point, have dependencies outside of that layer.

OrionMD
  • 389
  • 1
  • 7
  • 13
Neil
  • 993
  • 9
  • 9
17

I wrote an article for that topic: DTO vs Value Object vs POCO.

In short:

  • DTO != Value Object
  • DTO ⊂ POCO
  • Value Object ⊂ POCO
Vladimir
  • 1,630
  • 2
  • 18
  • 28
10

TL;DR:

A DTO describes the pattern of state transfer. A POCO doesn't describe much of anything except that there is nothing special about it. It's another way of saying "object" in OOP. It comes from POJO (Java), coined by Martin Fowler who literally just describes it as a fancier name for 'object' because 'object' isn't very sexy and people were avoiding it as such.

Expanding...

Okay to explain this in a far more high-brow way that I ever thought would be needed, beginning with your original question about DTOs:

A DTO is an object pattern used to transfer state between layers of concern. They can have behavior (i.e. can technically be a poco) so long as that behavior doesn't mutate the state. For example, it may have a method that serializes itself. For it to be a proper DTO, it needs to be a simple property bag; it needs to be clear that this object is not a strong model, it has no implied semantic meaning, and it doesn't enforce any form of business rule or invariant. It literally only exists to move data around.

A POCO is a plain object, but what is meant by 'plain' is that it is not special and does not have any specific requirements or conventions. It just means it's a CLR object with no implied pattern to it. A generic term. I've also heard it extended to describe the fact that it also isn't made to work with some other framework. So if your POCO has a bunch of EF decorations all over it's properties, for example, then it I'd argue that it isn't a simple POCO and that it's more in the realm of DAO, which I would describe as a combination of DTO and additional database concerns (e.g. mapping, etc.). POCOs are free and unencumbered like the objects you learn to create in school

Here some examples of different kinds of object patterns to compare:

  • View Model: used to model data for a view. Usually has data annotations to assist binding and validation for particular view (i.e. generally NOT a shared object), or in this day and age, a particular view component (e.g. React). In MVVM, it also acts as a controller. It's more than a DTO; it's not transferring state, it's presenting it or more specifically, forming that state in a way that is useful to a UI.
  • Value Object: used to represent values, should be immutable
  • Aggregate Root: used to manage state and invariants. should not allow references to internal entities other than by ID
  • Handlers: used to respond to an event/message.
  • Attributes: used as decorations to deal with cross-cutting concerns. May only be allowed to be used on certain objects levels (e.g. property but not class, method but not property, etc.)
  • Service: used to perform complex tasks. Typically some form of facade.
  • Controller: used to control flow of requests and responses. Typically restricted to a particular protocol or acts as some sort of mediator; it has a particular responsibility.
  • Factory: used to configure and/or assemble complex objects for use when a constructor isn't good enough. Also used to make decisions on which objects need to be created at runtime.
  • Repository/DAO: used to access data. Typically exposes CRUD operations or is an object that represents the database schema; may be marked up with implementation specific attributes. In fact, one of these schema DAO objects is actually another kind of DTO...
  • API Contracts: Likely to be marked up with serialization attributes. Typically needs to have public getters and setters and should be lightweight (not an overly complex graph); methods unrelated to serialization are not typical and discouraged.

These can be seen as just objects, but notice that most of them are generally tied to a pattern or have implied restrictions. So you could call them "objects" or you could be more specific about its intent and call it by what it is. This is also why we have design patterns; to describe complex concepts in a few words. DTO is a pattern. Aggregate root is a pattern, View Model is a pattern (e.g. MVC & MVVM).

A POCO doesn't describe a pattern. It is just a different way of referring to classes/objects in OOP which could be anything. Think of it as an abstract concept; they can be referring to anything. IMO, there's a one-way relationship though because once an object reaches the point where it can only serve one purpose cleanly, it is no longer a POCO. For example, once you mark up your class with decorations to make it work with some framework (i.e. 'instrumenting' it), it is no longer a POCO. Therefore I think there are some logical relationships like:

  • A DTO is a POCO (until it is instrumented)
  • A POCO might not be a DTO
  • A View Model is a POCO (until it is instrumented)
  • A POCO might not be View Model

The point in making a distinction between the two is about keeping patterns clear and consistent in effort to not cross concerns and lead to tight coupling. For example if you have a business object that has methods to mutate state, but is also decorated to hell with EF decorations for saving to SQL Server AND JsonProperty so that it can be sent back over an API endpoint. That object would be intolerant to change, and would likely be littered with variants of properties (e.g. UserId, UserPk, UserKey, UserGuid, where some of them are marked up to not be saved to the DB and others marked up to not be serialized to JSON at the API endpoint).

So if you were to tell me something was a DTO, then I'd probably make sure it was never used for anything other than moving state around. If you told me something was a view model, then I'd probably make sure it wasn't getting saved to a database, and I'd know that it's ok to put 'hacky' things in there to make sure the data is usable by a UI. If you told me something was a Domain Model, then I'd probably make sure it had no dependencies on anything outside of the domain and certainly no dependencies on any technical implementation details (databases, services etc.), only abstractions. But if you told me something was a POCO, you wouldn't really be telling me much at all other than it is not and should not be instrumented.

Example

This is a weak but accurate example that should be easy to follow.

This could be a POCO, it could also be a DTO. It's just an object; nothing special about it. Looks like a weakly typed property bag, but there's nothing notable about it.

public class CreateUserRequest
{
    public string Name { get; set; }

    public string Email { get; set; }
}

This is no longer a POCO

public class CreateUserRequest
{
    [JsonPropertyName(Name = "name")]
    public string Name { get; set; }

    [JsonPropertyName(Name = "email")]
    public string Email { get; set; }
}

Why isn't a POCO anymore? Because it is clearly a data contract that is instrumented to work with the System.Text.Json serializer. It's closer to a DTO now, but instrumented for a specific framework.

This next one is what happens when you don't make these distinctions

[Table("Users")]
public class CreateUserRequest
{
    [Key]
    [JsonIgnore]
    public string Id { get; set; }

    [JsonPropertyName(Name = "name")]
    public string Name { get; set; }

    [JsonPropertyName(Name = "email")]
    public string Email { get; set; }

    public int LoginCount { get; set; }

    public void IncrementLogin() => LoginCount++;
}

So now this is definitely not a POCO anymore. It looks to be a DTO of some sort, but it's purpose is overloaded. Is it an API contract or a DAO? It appears to be made to work as both a JSON contract AND with a database ORM. Additional instrumentation is required just to prevent it from leaking database PKs out of the REST API. It also has a method that mutates state as if someone is using this as a domain entity. It's not even clear if the developer intended the LoginCount to be part of the JSON contract or the database schema.

This class is something I see a lot from developers that think they're saving time by reusing classes. They think this is DRY. I suppose you could argue that it's DRY, but in reality, it's contrived, tightly coupled, probably violates 5 other design philosophies, and is just eventually going to screw you in the future.

History

Paraphrased from Fowler's explanation: In a world where objects were fancy (e.g. followed a particular pattern, had instrumentation etc.), it somehow encouraged people to avoid using not-fancy objects to capture business logic. So they gave it a fancy name POJO. If you want an example, the one he refers to is an "Entity Bean" which is one of those kinds of objects that have very specific conventions and requirements, etc.. If you don't know what that is --> Java Beans.

In contrast, a POJO/POCO is just the regular ole object that you'd learn how to create in school.

Sinaesthetic
  • 11,426
  • 28
  • 107
  • 176
  • "In a world where objects were fancy..." reminds of the GitHub drinking game: Go to GitHub. Type in a noun. If a package exists, you drink. If not, everyone else drinks. – Tim Feb 08 '23 at 21:20
9

I think a DTO can be a POCO. DTO is more about the usage of the object while POCO is more of the style of the object (decoupled from architectural concepts).

One example where a POCO is something different than DTO is when you're talking about POCO's inside your domain model/business logic model, which is a nice OO representation of your problem domain. You could use the POCO's throughout the whole application, but this could have some undesirable side effect such a knowledge leaks. DTO's are for instance used from the Service Layer which the UI communicates with, the DTO's are flat representation of the data, and are only used for providing the UI with data, and communicating changes back to the service layer. The service layer is in charge of mapping the DTO's both ways to the POCO domain objects.

Update Martin Fowler said that this approach is a heavy road to take, and should only be taken if there is a significant mismatch between the domain layer and the user interface.

Davy Landman
  • 15,109
  • 6
  • 49
  • 73
  • 2
    @David Landman, the link you included is for the Local DTO pattern, which is when DTOs are used for transfer state within your system boundary. In these cases, you should be very careful, since within your system you should already have a well defined domain that can be shared. When transferring state across system boundaries, the DTO is hard to avoid and pretty appropriate in all cases. – Michael Meadows May 26 '09 at 18:07
  • @Michal Meadows, yes, the link does indeed talk about a different subset of problems. But I think in the case of transferring state across a system boundary you should use a translation service to map the POCO from one context to the POCO from other context. Or are you talking about bounderies on a system level? – Davy Landman May 26 '09 at 19:55
1

DTO objects are used to deserialize data into objects from different sources. Those objects are NOT your Model (POCO) objects. You need to transform those objects into your Model (POCO) objects. The transformation is mostly a copy operation. You can fill those POCO objects directly from the source if its an internal source, but its not adviceable if its an external source. External sources have API's with descriptions of the Schema they use. Its much easier then to load the request data in an DTO and after that transform those in your POCO's. Yes its an extra step, but with a reason. The rule is to load the data from your source in an object. It can be JSON, XML whatever. When loaded then transform that data in what you need in your model. So most of times the DTO is an object image of the external source. Sometimes you even get the Schema's of the source providers then you can deserialize even easier, XML works like that with XSD's.

1

A primary use case for a DTO is in returning data from a web service. In this instance, POCO and DTO are equivalent. Any behavior in the POCO would be removed when it is returned from a web service, so it doesn't really matter whether or not it has behavior.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
  • 5
    I think your answer misrepresents what happens a little. In the case of a web service, a proxy is generated based on the exposed state of an object. This means a DTO is created separate from the POCO that just happens to have the same public state as the POCO. It may seem subtle, but it's important. The reason is that even if the proxy is identical to the original, it's not actually constructed from the same class. – Michael Meadows May 26 '09 at 17:53
  • Uh, no. One uses a DTO to return / receive data between tiers, in this case, a web service. One chooses a DTO because it has only data, and no behavior. It's true that the proxy class will also likely be a DTO, and that if you had used a POCO class instead, that a proxy would have been created. But in this case, the POCO class is effectively a DTO, since its behavior will not translate. I still say use a DTO because you won't miss behavior that never existed. – John Saunders May 26 '09 at 18:07
  • @John Saunders, Sorry if I wasn't clearer. I'm not arguing with the validity of your argument, but instead with the semantics of it. ** To your point: A DTO is meant to protect your POCOs from what you describe. In order for this to happen, DTOs must be mapped to the POCO. In simple to moderately complex solutions, this may be overkill, and therefore you're correct. – Michael Meadows May 26 '09 at 18:15
  • 5
    ** Semantically: Web services expose object state bags using WSDL. Proxies are generated from these. These cannot include behavior. If consuming a web service, the only relationship between your object and the exposed domain object is that it has the same public state created based on inspection. – Michael Meadows May 26 '09 at 18:15
  • @Michael: I have no idea what you're talking about. If you want that to change, then please post some citations or something. I've been using DTOs in web services for a while, and it was never in order to protect any POCO. It was in order to Transfer Data in an Object. – John Saunders May 26 '09 at 18:38
  • 7
    @John, I think you're overreacting. I'm saying you're right, but your wording is misleading. "In this case, POCO and DTO are equivalent." Semantically, that's not true. POCOs can be used as DTOs and vice versa, but that doesn't mean they're equivalent... no more than a car and pickup truck are equivalent, even though they can both be used to drive you to the grocery store. They have overlapping function, but you'd be hard pressed to find someone to tell you an insight is equivalent to an F350, even in the context of the grocery trip. – Michael Meadows May 26 '09 at 18:51
  • 4
    This answer is so very wrong, a web service is not generic enough for one. Most importantly it is a well established fact that DTO is NOT a POCO. DTO is a data container, while POCO are objects as properties and are persistence ignorant (no get or save methods). – Tom Stickel Dec 07 '11 at 21:16
-1

here is the general rule: DTO==evil and indicator of over-engineered software. POCO==good. 'enterprise' patterns have destroyed the brains of a lot of people in the Java EE world. please don't repeat the mistake in .NET land.

Arjan Tijms
  • 37,782
  • 12
  • 108
  • 140
benmmurphy
  • 2,503
  • 1
  • 20
  • 30
  • 7
    Could you elaborate, please? DTO are required when returning data from a web service, in order to avoid implementation and platform specifics in the contract. – John Saunders Apr 07 '09 at 14:57
  • 1
    Yes, John DTO's are designed for what you say and work well. But unfortunately they often get used when not required in single tier web apps and have little value. – Craig Apr 09 '09 at 02:54
  • 9
    I think, @drscroogemcduck, that maybe you dislike DTOs because they're used as a first resort rather than a last resort, but they're not inherently evil... no more so than the _infamous_ singleton or factory patterns. What is evil are the architects who shove frameworks down developers' throats that force them to make DTOs for everything. For what they do, transferring data, DTOs (if done prudently) are the perfect fit. – Michael Meadows May 26 '09 at 17:58
  • Its not Evil. It all comes down on good design. With bad design you indeed will overengineer. You will see that if everything in a web site is a Serviceable. Put everything in a DomainModel and aggregate where possible. Its wrong to create objects for everything. – Herman Van Der Blom Sep 29 '21 at 13:41
-14

Don't even call them DTOs. They're called Models....Period. Models never have behavior. I don't know who came up with this dumb term DTO but it must be a .NET thing is all I can figure. Think of view models in MVC, same dam** thing, models are used to transfer state between layers server side or over the wire period, they are all models. Properties with data. These are models you pass ove the wire. Models, Models Models. That's it.

I wish the stupid term DTO would go away from our vocabulary.

PositiveGuy
  • 46,620
  • 110
  • 305
  • 471
  • 1
    i don't know where you got this idea that models never have behavior. How do you model anything other than CRUD without modeling behavior? Even ViewModels have behavior in many cases, particularly in MVVM apps. DTO is a useful term because it accurately describes the purpose; to transfer data. – Gerald Apr 09 '15 at 14:12
  • 15
    downvoted for being factually incorrect, and for the pontificating attitude. – joedotnot Apr 13 '15 at 14:56
  • Nonsense. Models should be stupid containers. There is no DTO, it's a MS made up term. You transfer models between domains, services, and apps. Period. DTO is a waste of term that's not needed and only confuses things more. Models, Models and more Models that's it. Models may or may not have behavior. View Models should not. That behavior should be in a BL, not in the Model class. – PositiveGuy Apr 13 '15 at 19:25
  • I agree that DTO's are functionally Models. ViewModels have behavior and is what you bind to in MVVM. HOWEVER, I wrote an app where my Models were more intelligent (basically VMs but I didn't want to call them than) and they "accepted" a DTO object. This allowed me to have more options with the framework. So from CRUD (or even EF), I would transmit the object over WCF services and receive the DTO object and encapsulate it (adding OnProp Change, etc). My ViewModels performed further encapsulation and may have accepted two (or a list) of "Models". The rigid definition would be VMs. – SQLMason Sep 16 '15 at 19:58
  • "You transfer models between domains, services, and apps" Why do think the term model is more appropriate and fitting than the term DTO for this behaviour you describe? – caa Nov 30 '15 at 09:36