Search code examples
c#linq-to-sqlrepository-patternautomapperdto

Confusion between DTOs (linq2sql) and Class objects!


i have been successfully working with linq2sql and the linq DTOs (the classes that are created by linq2sql) ....

I am confused, i have the task of updating an old application and i can see that my DTOs will be used how they should be .... to transport date

I am using the repository pattern so i am passing data from the repository to the service via the linq2sql dtos... once i am in the service layer (this is basically my business logic) then I need to pass around class objects ..

these class objects are basicaly a mirror image (more or less) of the dtos - there are some changes in some place but generally the same..

So getting back to the question in hand! -- is this good practice to use dtos only to transport data from repository to service layer ... and once in the service layer(business logic) i should but MAPPING all my dtos to there class object counter parts (of course using automapper!!)

My other alternative is to continue to use the DTOS like class objects and pass them around from method to method and as return types etc but i feel this is bad practice and i keep going round in circles wondering which method i should apply?

Any help really appreciated

thanks


Solution

  • Here is my opinion: When dealing with any non-trival application. Using your linq2Sql objects as your domain model is a really bad idea. I see linq2Sql as an ORM and nothing more. Databases (which linq2Sql has a direct correspondance to) is a normalization of data. Classes (in the OOAD sense) are a normalization of behavior (not data).

    [these class objects are basicaly a mirror image]...

    I encountered this when building applications with linq2Sql. Lets be realistic....most line of business applications are glorified CRUD applications. So it isn't out of the question that a large percentage of your application's entities will correspond directly to database tables. I didn't want to be bound directly to the DTO's that were generated, but at the same time I didn't want duplicated classes littered across my application.

    So here is my solution:
    I "programmed to an interface".

    Lets say I have a PersonDto (Dto standing for Data Transfer Object) with properties of FirstName, LastName, Age (which relate directly to database columns).

    I created an IPerson interface and had my PersonDto implement it.

    
      [Table(Name="Persons")]
      internal class PersonDto : IPerson
      {
          ....
      }
    
    

    And my repository method would take in and retrieve IPerson as opposed to the Linq2Sql class.

    
        IPerson somePerson = _repository.Get(someGuid);
        somePerson.FirstName = "SomeName";
        _repository.Save(somePerson);
    
    

    This approach has worked really well for me. Whenever I feel I need to deviate from the DTO, I can do so fairly easily because of the interface representing my object as opposed to the DTO.

    Some general pointers: Build your DTO's by hand...I know it sounds crazy, but you'll find that it works really well with a top down, test driven development approach. Your DTO's (linq2Sql) objects will be extremely light and will be open to changes outside of the .dbml designer.

    Keep your DTO's and DataContext's internal. There is no reason for your dto's to be exposed publicly (given that you have public interfaces for you repositories and domain objects). Doing this will force a logical separation between your domain model and data access.

    Put all of your data access layer in a separate project (again to enforce this separation).

    Put your interface declarations in a separate project (this will ensure you don't run into any circular references).

    Hope this helps...