Saturday, March 14, 2009

What is the Difference Between a DTO and a POCO?

First off, I’m not the authority on DTOs, POCOs, object oriented architecture, or really anything now that I stop to think about it.  However, I do use a DTO / POCO centric architecture whenever I can and there’s at least one former client of mine who is now saddled with an entity class named DevicePoco (there was already a Device entity object that followed the Active Record pattern, otherwise I would never have named an object XXXPoco). When my client saw the new object with the crazy name in their BAL, their first reaction was of course to ask “What the heck is a POCO?”  Not too long ago I was at a Visual Studio User Group meeting where the question of POCOs and how they are different from DTOs came up.  The presenter, who quite honestly is a much better developer than me, stated confidently that POCOs and DTOs are the same thing.  I immediately clamped both hands over my mouth to keep from screaming “They are not!”.  So, there seems to be a lack of good information in the .Net community about what these objects are.  I’m going to try and clarify the issue.

What is a Data Transfer Object (DTO)?

Normally this is where I would say Wikipedia defines a DTO as...  Unfortunately, the current Wikipedia definition is pretty awful except for the line:  

“The difference between Data Transfer Objects and Business Objects or Data Access Objects is that a DTO does not have any behaviour except for storage and retrieval of its own data (accessors and mutators).”

That’s the key concept.  A DTO stores data.  It has no methods (behaviors) other than accessors and mutators which are just used to get and set data.  Why make an object that simple? Because they make a great, lightweight, strongly typed data container when you want to move data from your DAL to your BAL or between the umpteen layers in your n-tier architecture.  Below is the code for the PersonDTO that I’ve been using in many of my recent posts. You’ll notice that it really does nothing except store data.

public class PersonDTO : DTOBase

{

    public Guid PersonGuid { get;set; }

    public int PersonId { get; set; }

    public DateTime UtcCreated { get; set; }

    public DateTime UtcModified { get; set; }

    public string Password { get; set; }

    public string Name { get; set; }

    public string Nickname { get; set; }

    public string PhoneMobile { get; set; }

    public string PhoneHome { get; set; }

    public string Email { get; set; }

    public string ImAddress { get; set; }

    public int ImType { get; set; }

    public int TimeZoneId { get; set; }

    public int LanguageId { get; set; }

    public string City { get; set; }

    public string State { get; set; }

    public int ZipCode { get; set; }

 

 

    // Constructor

    // No parameters and all value types are intialized to the

    // null values defined in CommonBase.

    public PersonDTO()

    {        

        PersonGuid = Guid_NullValue;

        PersonId = Int_NullValue;

        UtcCreated = DateTime_NullValue;

        UtcModified = DateTime_NullValue; 

        Name = String_NullValue;

        Nickname = String_NullValue;

        PhoneMobile = String_NullValue;

        PhoneHome = String_NullValue;

        Email = String_NullValue;

        ImAddress = String_NullValue;

        ImType = Int_NullValue;

        TimeZoneId = Int_NullValue;

        LanguageId = Int_NullValue;

        City = String_NullValue;

        State = String_NullValue;

        ZipCode = Int_NullValue;

        IsNew = true;

    }

}

So, to sum up, a DTO is just a collection of properties (or data members).  It has no validation, no business logic, no logic of any kind.  It’s just a simple, lightweight data container used for moving data between layers.

So What’s a POCO?

A POCO is not a DTO.  POCO stands for Plain Old CLR Object, or Plain Old C# Object.  It’s basically the .Net version of a POJO, Plain Old Java Object.  A POCO is your Business Object.  It has data, validation, and any other business logic that you want to put in there.  But there’s one thing a POCO does not have, and that’s what makes it a POCO.  POCOs do 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. 

Below is the code for my BAL.Person class which is a POCO.  You’ll notice that it contains no persistence logic of any kind, just data and validation methods.  You’ll also notice that I don’t recreate a bunch of accessors and mutators for my person data.  That would clutter up my Person class, plus they would be redundant since they’ve already been defined in PersonDTO.  Instead I just have a single property named Data that is of type PersonDTO.  This approach makes getting and saving a person really easy.  When getting a person, I just get a PersonDTO from my DAL and then set person.Data = personDTO.  When saving, my save methods all take a PersonDTO as a parameter so I can just use my person.Data property for that as well.

public class Person : BALBase

{

        // Data

        // This property exists for all BAL objects, and it is

        // set to the DTO type for this entity.  This is the

        // mechanism that we use to implement "has a" inheritance

        // instead of "is a" inheritance.

        public PersonDTO Data { get; set; }

 

 

        // Person - default constructor

        public Person() {this.Data = new PersonDTO();}

        // Person - takes a DTO

        public Person(PersonDTO dto) {this.Data = dto;}

 

 

          // Validate

        public override List<ValidationError> Validate()

        {

            // Call all validation functions

            Val_Name();

            Val_Email();

            Val_Password();

            Val_TimeZone();

            Val_City();

            Val_State();

            Val_ZipCode();

            Val_ImType();

 

            // If the ValidationErrors list is empty then

            // we passed validation.

            return this.ValidationErrors;

        }

 

 

        // Validation Methods:

        // There are only 2 requirements on validation methods.

        //  - They must handle adding a Validation Error to the

        //    ValidationErrors list if they find an error.

        //  - You must manually add a call to all validation methods

        //    to the Validate() function.

        //  When creating a new ValidationError object, remember

        //  that the first parameter is the exact name of the field

        //  that has the bad value, and the error message should

        //  not contain the field name, but instead the <FieldName>

        //  tag, which will be replaced by the UI or consuming app.

 

        // Val_Name

        public bool Val_Name()

        {

            // Name required

            if (this.Data.Name == DTOBase.String_NullValue)

            {

                this.ValidationErrors.Add(new ValidationError("Person.Name", "<FieldName> is required"));

                return false;

            }

            else

            {

                return true;

            }

        }

 

        // You get the idea.  I’m leaving out the rest of the validation code

        // so you don’t go blind reading the same lines over and over.

}

No persistence logic there, just data and validation logic.  So you’re probably thinking, if the persistence logic doesn’t go in my entity class, then where does it go?  The answer is, another class.  POCOs must be hydrated by some other class that encapsulates the persistence logic for that entity, like a repository or a data controller.  I typically use a repository.  For this example I used a PersonRepository class that encapsulates the logic for getting a new person object, getting a personDTO from the DAL, and then setting person.Data = personDTO. Same with the save.  My PersonRepository class has a SavePerson() method that takes a full person object then passes its person.Data value to the DAL to be persisted.  Code for getting and setting a person entity in my UI looks like this:

hydrate from db:

Person person = PersonRepository.GetPersonByEmail(email);

 

save to db:

PersonRepository.SavePerson(ref person, true);

Why Would I Ever Want to Do This?

The next question you might ask is What’s the point?  Why should I use these patterns instead of just using DataTables and putting all my persistence logic in my entity objects?  That answer is a little tougher.  I prefer a POCO / Repository / DTO architecture, but it’s not the one right way to design an application.  I think the benefits are that it is a very clean and easy to maintain architecture.  It provides separation of business logic and persistence logic, which is more in line with the Single Responsibility Principle.  Using POCOs with DTOs and a well designed DAL is just about the best performing architecture you can build, see my series on High Performance DAL Architecture. But, I think most .Net developers will be driven to use POCOs and repositories (but not DTOs) by ORMs.  Entity Framework, nHibernate, and a lot of the ORMs out there require or assume a POCO type architecture. In fact, Entity Framework has introduced an IPOCO interface which I’m having trouble finding documentation on but it sounds like something good. Also, if you want to get into Domain Driven Design, you’ve got to embrace the POCO.  In his excellent book Applying Domain-Driven Design and Patterns, Jimmy Nilsson even has a section titled “POCO as a Lifestyle”. 

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.

33 comments:

  1. Rudy, good article. I like the DTO concept but didn't know it had a TLA :-) (I have used a struct for this purpose.) I hate passing datatables around the app. But, what do you do when your datagrid or other control has to have a datatable to bind to? Arguably, the code behind should build a datatable from the DTO, just to bind the grid to. After all, it's only the presentation layer that wants the data in that type of object.

    - Mark G.

    ReplyDelete
  2. Mark G. - you can use an ObjectDatasource to bind your grids directly to classes like Rudy's repository classes without using Datatables. There is a great walkthrough of how to do this here - http://imar.spaanjaars.com/QuickDocId.aspx?quickdoc=420

    ReplyDelete
  3. Hi, Thanks for the comments. BTW, you can bind a generic list of your own custom classes, even without the ObjectDataSource. I usually handle all of my data binding explicitly in the code behind page without any kind of datasource in the markup. I just get my generic list, then if I'm binding to a DDL I'll set the DataSource, DataTextField, and DataValueField properties.

    ReplyDelete
  4. I am just waadering: if validation fails what is the state of the object? is it a valid one?

    ReplyDelete
  5. Just thought I'd add a few comments about DDD. It's really all about business rules. Where are my business rules? Go look in the classes in your domain layer. That's where you'll find them. Also, any discussion of DDD must include mention of Aggregrates (research if you don't know). Lastly, I think domain object properties always must be valid. If an invalid value is passed in, it should throw an exception, then and there. But what if you want a list of all invalid properties? Then pass in a DTO to a method that takes a DTO and adds exception handling around each setter to build out a list of errors. If the list is not empty, then throw an exception from that method that returns the full details of all invalid properties.

    ReplyDelete
  6. Just to clarify my previous post, you shouldn't have a Validate method on your domain object, because then you are assuming that the client is going to call the Validate method.
    Instead, the domain object should always be valid. In addition, validation on child objects of an aggregrate should be placed in the aggregate, and those child objects should not be exposed to the outside world (only the aggregate is exposed). Rather, the aggregate can expose a property, if needed, that wraps the child object and thus gives the aggregate a chance to validate any changes being made to the child object.

    ReplyDelete
  7. Hi Anonymous. You're stating a few things that are definitely just your opinion as though they are fact and accepted best practice. To say that POCOs shouldn't have validation because you shouldn't be able to create them unless the data is valid is nonsense. Not only can you create POCOs with invalid data, I’ve even heard arguments that you should be able to persist invalid data. I try to keep myself from thinking there’s one right way to build an application, but I would say that validation on the domain objects is a pretty common practice for people who are producing real production code with DDD. I can’t thing of a better way it could work. But if you have code that demonstrates a different design, post a link to it. I would love to take a look.

    ReplyDelete
  8. This comment has been removed by the author.

    ReplyDelete
  9. Good post Rudy. I always like to transform my ORM's DTOs into POCOS... I would also like to inherit my POCOs from POCO interfaces, but my seniors are not a big fans of that :-p

    ReplyDelete
  10. H!
    So who calls the repository? do you have some other layer or is it from the GUI?
    also.. just a nit pick..
    Any reason you're not cascading your constructors? you have..
    // Person - default constructor
    public Person() {this.Data = new PersonDTO();}
    // Person - takes a DTO
    public Person(PersonDTO dto) {this.Data = dto;}

    Why not.
    // Person - default constructor
    public Person():this(new PersonDTO()){} //**
    // Person - takes a DTO
    public Person(PersonDTO dto) {this.Data = dto;}

    ReplyDelete
  11. Much thanks for the article. If you can, please take a look at
    http://stackoverflow.com/questions/1793576/ddd-concepts-in-n-layer-development

    ReplyDelete
  12. Hmm, this brings some questions in my mind.

    I am creating a simple OR/M mapping prototype with identity map, repository, unit of work etc.

    Now the question is - what should a mapper map then? Database to DTO or database to POCO?

    I agree that sometimes there may be no reasons to map to a POCO. For example, if I know that all I want is a bunch of records (and maybe even with paging) that I want to feed to some report-like web form then I do not need to bother with POCO when reading data. When the user choses a record and clicks "Edit" - then I can construct a POCO if needed - if there is some business logic for reading (but I guess that is rarely so, then again DTO will be good). But when the user submits data, then obviously he sends me a DTO to my BAL, there I create a POCO, do validation and business logic stuff, and if everything is fine then I get unit of work, pass my POCOs to it and Commit.

    That means I have to implement my Repository so it can return DTOs and POCOs as needed. But then - why I do need DTOs at all if I can have a HashMap with [string field, object value]? It would serialize over XML automatically just fine if I need to use it with web services.

    If I want to give domain developers freedom how they validate their domain entities, then I should not force each domain entity to _have_ a DTO. This would not be a good PI. What if they want to validate some fields in setters? Then my domain object must inherit from DTO so designers can override setters as needed - but again not a PI-ish to force inheriting. It must be a domain developer's choice - to _have_ DTO, to _inherit_ DTO or not have a DTO at all.

    Then how should I organize OR/mapping if I definitely need to support both - DTO and POCO? Would it be overkill to map to both - POCOs and DTOs (when reading from database - obviously storing would need POCOs anyway)? Also it would be hard to implement identity map - I'll have to track where are DTOs, POCOs and when they change.

    ReplyDelete
  13. Why not set the setter of the PersonGuid to internal to protect it for the Gui?

    ReplyDelete
  14. Overall, an interesting post. Some questions and concerns came to mind (some of which are similar to previous comments).

    * Why not use a struct for the DTO?
    * I don't like that the Validate method changes the state of the object. It just feels wrong that Validate() has a side effect. Is there an alternative to this that you like?
    * Why do you say that DTOs won't be used by most developers?

    Finally, are there any good online resources that outline the same structure as above? Specifically, I'm looking for more examples of POCOs with "has a" relationships to DTOs.

    ReplyDelete
  15. Who would call the Validate() method? If the POCO is not suppose to have any persistance logic i.e. a Save() method, then the repository is the only one to execute validation i.e. PersonRepository.SavePerson() { Validate(); Save(); } But isn't this putting business logic in the repository (DAL)? My concern is that the validation is now executed by the repository, not the business object.

    ReplyDelete
  16. nice work but i would say that if anyone make a website project in asp.net and access data from data base via DTO and upload that project along with sample data base on this site

    ReplyDelete
  17. Sorry I don't understand why your POCO would not contain public properties (your accessors). Surely a consumer of your POCO, such as an ASP.NET page will expect to be able to get and set properties of that domain object and do so on the object itself, not on a DTO?

    Could you please provide an example of how you see an aspx work with this domain model? I just don't get it.

    Thanks.

    ReplyDelete
  18. Just saw the question from Rob. Just to clarify the POCO does have public accessors. In the example in this post I have all of my data encapsulates in a Data property of type PersonDTO. So to access data for a person POCO you would use syntax like person.Data.FirstName, person.Data.Email. This method allowed me easily move data between a DTO and POCO. I'm not sure if that's the best design but I was trying to make sure I only had one place in my code that would need to change if I ever added a field to Person.

    ReplyDelete
  19. nice article , clears DTO concepts.

    Ravi kore

    ReplyDelete
  20. i use dtos heavily in my asp.net mvc web applications. all properties in the dto are either string datatype or another dto type. this is huge because i can do ALL validations in a validation layer. What i mean by this, is we used to put some validation in the controller methods (i.e., was a required value provided, was it numeric as expected, etc), and then if all of the form inputs were the correct data types, we would then validate the business logic. Now, our fields are named "ExampleDto.FieldName" and they are of type string. So, if someone types in DLKSJFDS for a numeric field, it won't bomb when I try to pass it into a decimal property on my domain object. I can fully validate in one spot, my controllers have zero validation code in them. I think it works well.

    ReplyDelete
  21. I enjoyed reading it.. now I am better explained

    ReplyDelete
  22. Rudy, I must say this is really good article and clear doubts about DTO/POCO. Do you recommend any article/book for different design pattern with really simple example like you have explain this article about DTO/POCO/Repository architecture. We have been coding pretty simple way not following any pattern so as I gain more experience in .net I must have knowledge about that and should be following best practice.

    Thanks in advance.

    ReplyDelete
  23. Thanks. That's a great clean and simple explanation on this topic. You are right there's a lot of misleading information out there.

    ReplyDelete
  24. Thank you, your article relieve the pain of my head. (Relation between DTO and POCO). I like your architecture, it's very clean and easy to maintain.

    ReplyDelete
  25. Nice article...Got my concepts cleared to a great extent!!

    ReplyDelete
  26. Just out of curiosity, can you share your DTOBase.cs file? I am wondering what you did for nullable ints.

    ReplyDelete
    Replies
    1. Never mind. I found it here in another article you wrote.
      http://rlacovara.blogspot.com/2009/02/high-performance-data-access-layer.html

      Delete
  27. Really great article!!! Thank you very much!

    ReplyDelete
  28. Good Article...

    ReplyDelete
  29. Thank you. :) very interesting.

    ReplyDelete