What is the Difference Between a DTO and a POCO?

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.

Source : https://rlacovara.blogspot.com/2009/03/what-is-difference-between-dto-and-poco.html

 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.