web-dev-qa-db-ja.com

データ転送オブジェクトパターン

エンタープライズアプリケーションとデザインパターンの初心者です。この問題は、デザインパターンに関する知識の不足が原因である可能性があります。 DTOを使用してデータを転送する方が良いことがわかりました。

以下の私のビジネスエンティティクラス:

public class Patient
{    
    public string ID { get; set; }
    public string FullName { get; set; }
    public string FirstName { get; set; }
    public string Surname { get; set; }
}

したがって、私のアプリケーションユーザーでは、IDとHospitalIDのみを指定します。別のWebサービスを呼び出して個人情報を取得します

 public class PersonDTO
 {
     public string NIC { get; set; }
     public string FullName { get; set; }
     public string FirstName { get; set; }
     public string BirthPlace { get; set; }
     public string BirthCertificateID { get; set; }
 }

したがって、これらの情報に基づいて、患者オブジェクトに行きます。 (DTOパターンを使用)

だから私はこれを次のように変換する新しいクラスを書くことを考えました。

public class PatientDO
{
    public static Patient ConvertToEntity(
        PatientRegistrationDTO pregDTO,
        PersonDTO person
    )
    {
        Patient p = new Patient();
        p.NIC = pregDTO.NIC;
        p.FullName = person.FullName;
        p.FirstName = person.FirstName;
        return p;
    }
}

しかし、最近 articles をいくつか読んだところ、Serializer Helper classXmlSerializerを使用しました。なぜこのようなものを使用したのか理解できません。

dTOパターンの場合、XmlSerializerを使用する必要があり、なぜそれが使用されるのですか?

14
DevT

AutoMapperを実際に確認する必要があります。

http://automapper.org

これは、あるクラスから別のクラスに値を自動的にマップするソリューションに含めることができるソフトウェアです。

同じ名前のプロパティを自動的にマッピングし、子オブジェクトに関してもかなりスマートです。ただし、必要なときに完全なマッピング制御も提供します。

[〜#〜]編集[〜#〜]

AutoMapperの動作を示すいくつかの例。実際にこのようなコードを作成することはありません。簡潔!

クラスの例。

// Common scenario.  Entity classes that have a connection to the DB.
namespace Entities 
{
   public class Manager
   {
      public virtual int Id { get; set; }
      public virtual User User { get; set; }
      public virtual IList<User> Serfs { get; set; }
   }

   public class User
   {
      public virtual int Id { get; set; }
      public virtual string Firstname { get; set; }
      public virtual string Lastname { get; set; }
   }
}



// Model class - bit more flattened
namespace Models 
{
   public class Manager 
   {
      public int Id { get; set; }
      public string UserFirstname { get; set; }
      public string UserLastname { get; set; }
      public string UserMiddlename { get; set; }
   }
}

通常、プロジェクトの一部ですべてのオートマッピングを構成します。今示した例では、Entities.ManagerとModels.Managerの間のマップを次のように構成できます。

// Tell AutoMapper that this conversion is possible
Mapper.CreateMap<Entities.Manager, Models.Manager>();

次に、コードで、次のようなものを使用して、エンティティバージョンから新しいModels.Managerオブジェクトを取得します。

// Map the class
var mgr = Map<Entities.Manager, Models.Manager>
  ( repoManager, new Models.Manager() );

ちなみに、AMは、物事に一貫した名前を付ければ、多くのプロパティを自動的に解決できるほど賢いです。

上記の例では、次の理由により、UserFirstnameとUserLastnameが自動的に入力されます。

  • ManagerにはUserというプロパティがあります
  • ユーザーにはFirstnameとLastnameというプロパティがあります

ただし、UsersにはMiddlenameというパブリックプロパティがないため、Entities.ManagerとModels.Managerの間のマッピング操作後は、Models.ManagerのUserMiddlenameプロパティは常に空白になります。

20

CodeProjectには、素晴らしくシンプルなデモがあります。それを通過する価値があります。初心者は、DTOを設計する基本的なアイデアを得ることができます。

http://www.codeproject.com/Articles/8824/C-Data-Transfer-Object

コンテンツの概要は次のとおりです。

データ転送オブジェクト「DTO」は、アプリケーションの複数のレイヤー間でデータを転送するために使用される単純なシリアル化可能なオブジェクトです。 DTOに含まれるフィールドは通常、文字列、ブール値などのプリミティブ型です。他のDTOがDTOに含まれたり、集約されたりする場合があります。たとえば、LibraryDTOに含まれるBookDTOのコレクションがあるとします。複数のアプリケーションで使用されるフレームワークを作成し、DTOを利用して階層間でデータを転送しました。フレームワークは他のOOファクトリ、ファサードなどのパターンにも依存しています。DataSetと比較したDTOの優れた点の1つは、DTOがデータに直接一致する必要がないことです。テーブルまたはビュー。DTOは別のDTOからフィールドを集約できます。

これは、すべてのデータ転送オブジェクトの基本クラスです。

using System;

namespace DEMO.Common
{
/// This is the base class for all DataTransferObjects.
    public abstract class DTO
    {
        public DTO()
        {
        }
    }
}

これは、DTOからの派生クラスです。

using System;
using System.Xml.Serialization;
using DEMO.Common;

namespace DEMO.DemoDataTransferObjects
{
public class DemoDTO : DTO
{
    // Variables encapsulated by class (private).
    private string demoId = "";
    private string demoName = "";
    private string demoProgrammer = "";

    public DemoDTO()
    {
    }

    ///Public access to the DemoId field.
    ///String
    [XmlElement(IsNullable=true)]
    public string DemoId
    {
        get
        {
            return this.demoId;
        }
        set
        {
            this.demoId = value;
        }
    }

    ///Public access to the DemoId field.
    ///String
    [XmlElement(IsNullable=true)]
    public string DemoName
    {
        get
        {
            return this.demoName;
        }
        set
        {
            this.demoName = value;
        }
    }

    ///Public access to the DemoId field.
    ///String
    [XmlElement(IsNullable=true)]
    public string DemoProgrammer
    {
        get
        {
            return this.demoProgrammer;
        }
        set
        {
            this.demoProgrammer = value;
        }
    }

}

これは、DTOのヘルパークラスです。 DTOをシリアル化および逆シリアル化するパブリックメソッドがあります。

using System;
using System.Xml.Serialization;
using System.IO;

namespace DEMO.Common
{
public class DTOSerializerHelper
{
    public DTOSerializerHelper()
    {
    }

    /// 
    /// Creates xml string from given dto.
    /// 
    /// DTO
    /// XML
    public static string SerializeDTO(DTO dto)
    {
        try
        {
            XmlSerializer xmlSer = new XmlSerializer(dto.GetType());
            StringWriter sWriter = new StringWriter();
            // Serialize the dto to xml.
            xmlSer.Serialize(sWriter, dto);
            // Return the string of xml.
            return sWriter.ToString();
        }
        catch(Exception ex)
        {
            // Propogate the exception.
            throw ex;
        }
    }

    /// 
    /// Deserializes the xml into a specified data transfer object.
    /// 
    /// string of xml
    /// type of dto
    /// DTO
    public static DTO DeserializeXml(string xml, DTO dto)
    {
        try
        {
            XmlSerializer xmlSer = new XmlSerializer(dto.GetType());
            // Read the XML.
            StringReader sReader = new StringReader(xml);
            // Cast the deserialized xml to the type of dto.
            DTO retDTO = (DTO)xmlSer.Deserialize(sReader);
            // Return the data transfer object.
            return retDTO;
        }
        catch(Exception ex)
        {
            // Propogate the exception.
            throw ex;
        }            
    }

}

次にシリアライズ/デシリアライズを開始します。

using System;
using DEMO.Common;
using DEMO.DemoDataTransferObjects;

namespace DemoConsoleApplication
{
public class DemoClass
{
    public DemoClass()
    {
    }

    public void StartDemo()
    {
        this.ProcessDemo();
    }

    private void ProcessDemo()
    {
        DemoDTO dto = this.CreateDemoDto();

        // Serialize the dto to xml.
        string strXml = DTOSerializerHelper.SerializeDTO(dto);

        // Write the serialized dto as xml.
        Console.WriteLine("Serialized DTO");
        Console.WriteLine("=======================");
        Console.WriteLine("\r");
        Console.WriteLine(strXml);
        Console.WriteLine("\r");

        // Deserialize the xml to the data transfer object.
        DemoDTO desDto = 
          (DemoDTO) DTOSerializerHelper.DeserializeXml(strXml, 
          new DemoDTO());

        // Write the deserialized dto values.
        Console.WriteLine("Deseralized DTO");
        Console.WriteLine("=======================");
        Console.WriteLine("\r");
        Console.WriteLine("DemoId         : " + desDto.DemoId);
        Console.WriteLine("Demo Name      : " + desDto.DemoName);
        Console.WriteLine("Demo Programmer: " + desDto.DemoProgrammer);
        Console.WriteLine("\r");
    }

    private DemoDTO CreateDemoDto()
    {
        DemoDTO dto = new DemoDTO();

        dto.DemoId            = "1";
        dto.DemoName        = "Data Transfer Object Demonstration Program";
        dto.DemoProgrammer    = "Kenny Young";

        return dto;
    }
}

最後に、このコードはメインアプリケーションで実行されます

static void Main(string[] args)
{
    DemoClass dc = new DemoClass();
    dc.StartDemo();
}
3
Venugopal M

XmlSerializerまたはJsonSerializerを使用して、ソース(Webサービス)からXMLまたはJsonデータをシリアル化(ロード)できます。または、DTOという名前の説明:データをソース(Webサービス)から(一般的なDTO)オブジェクトにシリアル化(転送)します。したがって、DTOは汎用オブジェクトです。可能な限り広いDTOオブジェクトを作成し、それを完全に埋めることで、そのオブジェクトから好きなように使用し、「独自の」プログラムオブジェクトにコピーできる場合があります。

例:交通ナビゲーションデータを表示するプログラムを開発しました。 XMLまたはjsonメッセージ全体をDTOオブジェクトでシリアル化します。このDTOオブジェクトにはより多くの情報が含まれており、プログラムで必要になるため、別の形式にすることができるため、必要なものだけを使用します。 DTOオブジェクトを使用すると、ソース(Webサービス)からデータを簡単に抽出できます。

「Auto」という名前のため、AutoMapperを使用したくありません。私は何をしているのかを知り、私のデータがどこに行くのかを考えたいです。

1