วิธีใช้ Data Transfer Objects ใน ASP.NET Core 3.1

วัตถุการถ่ายโอนข้อมูล (โดยทั่วไปเรียกว่า DTO) เป็นอินสแตนซ์ของคลาส POCO (วัตถุ CLR เก่าธรรมดา) ที่ใช้เป็นคอนเทนเนอร์เพื่อห่อหุ้มข้อมูลและส่งผ่านจากชั้นหนึ่งของแอปพลิเคชันไปยังอีกชั้นหนึ่ง โดยทั่วไปคุณจะพบว่ามีการใช้ DTO ในชั้นบริการเพื่อส่งคืนข้อมูลกลับไปที่เลเยอร์การนำเสนอ ข้อได้เปรียบที่ใหญ่ที่สุดของการใช้ DTO คือการแยกลูกค้าออกจากโครงสร้างข้อมูลภายในของคุณ

บทความนี้กล่าวถึงเหตุผลที่เราควรใช้ Data Transfer Objects และวิธีที่เราสามารถทำงานกับวัตถุเหล่านี้ใน ASP.NET Core 3.1 ในการทำงานกับตัวอย่างโค้ดที่ให้ไว้ในบทความนี้คุณควรติดตั้ง Visual Studio 2019 ในระบบของคุณ หากคุณยังไม่มีสำเนาคุณสามารถดาวน์โหลด Visual Studio 2019 ได้ที่นี่ 

สร้างโครงการ ASP.NET Core 3.1 API

ก่อนอื่นมาสร้างโครงการ ASP.NET Core ใน Visual Studio สมมติว่ามีการติดตั้ง Visual Studio 2019 ในระบบของคุณให้ทำตามขั้นตอนที่ระบุไว้ด้านล่างเพื่อสร้างโครงการ ASP.NET Core API ใหม่ใน Visual Studio

  1. เปิด Visual Studio IDE
  2. คลิกที่ "สร้างโครงการใหม่"
  3. ในหน้าต่าง“ สร้างโครงการใหม่” เลือก“ ASP.NET Core Web Application” จากรายการเทมเพลตที่แสดง
  4. คลิกถัดไป 
  5. ในหน้าต่าง "กำหนดค่าโครงการใหม่ของคุณ" ระบุชื่อและตำแหน่งของโครงการใหม่
  6. คลิกสร้าง 
  7. ในหน้าต่าง“ Create New ASP.NET Core Web Application” ที่แสดงถัดไปให้เลือก. NET Core เป็นรันไทม์และ ASP.NET Core 3.1 (หรือใหม่กว่า) จากรายการดรอปดาวน์ที่ด้านบน
  8. เลือก“ API” เป็นเทมเพลตโครงการเพื่อสร้างแอปพลิเคชัน ASP.NET Core API ใหม่ 
  9. ตรวจสอบให้แน่ใจว่าไม่มีการเลือกช่องทำเครื่องหมาย "เปิดใช้งานการสนับสนุน Docker" และ "กำหนดค่าสำหรับ HTTPS" เนื่องจากเราจะไม่ใช้คุณลักษณะเหล่านั้นที่นี่
  10. ตรวจสอบให้แน่ใจว่าการรับรองความถูกต้องถูกตั้งค่าเป็น“ ไม่มีการพิสูจน์ตัวตน” เนื่องจากเราจะไม่ใช้การพิสูจน์ตัวตน
  11. คลิกสร้าง 

สิ่งนี้จะสร้างโครงการ ASP.NET Core API ใหม่ใน Visual Studio เราจะใช้โครงการนี้เพื่อทำงานกับ Data Transfer Objects ในส่วนถัดไปของบทความนี้

เหตุใดจึงต้องใช้ Data Transfer Objects (DTOs)

เมื่อออกแบบและพัฒนาแอปพลิเคชันหากคุณใช้แบบจำลองเพื่อส่งผ่านข้อมูลระหว่างเลเยอร์และส่งข้อมูลกลับไปยังเลเยอร์การนำเสนอคุณจะเปิดเผยโครงสร้างข้อมูลภายในของแอปพลิเคชันของคุณ นั่นเป็นข้อบกพร่องในการออกแบบที่สำคัญในแอปพลิเคชันของคุณ

การแยกเลเยอร์ DTO ของคุณทำให้ชีวิตง่ายขึ้นเมื่อคุณใช้ API แอปพลิเคชัน MVC และรูปแบบการส่งข้อความเช่น Message Broker DTO เป็นตัวเลือกที่ยอดเยี่ยมเมื่อคุณต้องการส่งผ่านวัตถุน้ำหนักเบาข้ามสายโดยเฉพาะอย่างยิ่งเมื่อคุณส่งวัตถุของคุณผ่านสื่อที่ จำกัด แบนด์วิดท์

ใช้ DTO สำหรับนามธรรม

คุณสามารถใช้ประโยชน์จาก DTO เพื่อแยกวัตถุโดเมนของแอปพลิเคชันของคุณจากอินเทอร์เฟซผู้ใช้หรือเลเยอร์การนำเสนอ ในการทำเช่นนั้นเลเยอร์การนำเสนอของแอปพลิเคชันของคุณจะถูกแยกออกจากชั้นบริการ ดังนั้นหากคุณต้องการเปลี่ยนเลเยอร์การนำเสนอคุณสามารถทำได้อย่างง่ายดายในขณะที่แอปพลิเคชันจะยังคงทำงานกับเลเยอร์โดเมนที่มีอยู่ ในทำนองเดียวกันคุณสามารถเปลี่ยนเลเยอร์โดเมนของแอปพลิเคชันของคุณได้โดยไม่ต้องเปลี่ยนเลเยอร์การนำเสนอของแอปพลิเคชัน

ใช้ DTO สำหรับการซ่อนข้อมูล

อีกเหตุผลหนึ่งที่คุณต้องการใช้ DTO คือการซ่อนข้อมูล นั่นคือโดยใช้ DTO คุณสามารถส่งคืนเฉพาะข้อมูลที่ร้องขอ ตัวอย่างเช่นสมมติว่าคุณมีเมธอดชื่อ GetAllEmployees () ที่ส่งคืนข้อมูลทั้งหมดที่เกี่ยวข้องกับพนักงานทั้งหมด ลองอธิบายสิ่งนี้โดยการเขียนโค้ด

ในโครงการที่เราสร้างไว้ก่อนหน้านี้ให้สร้างไฟล์ใหม่ชื่อ Employee.cs เขียนโค้ดต่อไปนี้ภายในไฟล์นี้เพื่อกำหนดคลาสโมเดลที่ชื่อว่า Employee

พนักงานระดับสาธารณะ

    {

        รหัส int สาธารณะ {get; ชุด; }

        สตริงสาธารณะ FirstName {get; ชุด; }

        สตริงสาธารณะ LastName {get; ชุด; }

        สตริงสาธารณะ DepartmentName {get; ชุด; }

        ทศนิยมสาธารณะ Basic {get; ชุด; }

        ทศนิยมสาธารณะ DA {รับ; ชุด; }

        HRA ทศนิยมสาธารณะ {get; ชุด; }

        NetSalary ทศนิยมสาธารณะ {get; ชุด; }

    }

หมายเหตุคลาสพนักงานประกอบด้วยคุณสมบัติ ได้แก่ Id, FirstName, LastName, Department, Basic, DA, HRA และ NetSalary อย่างไรก็ตามเลเยอร์การนำเสนออาจต้องการเพียง Id, FirstName, LastName และชื่อแผนกของพนักงานจากเมธอด GetAllEmployees () เท่านั้น หากวิธีนี้ส่งกลับรายการทุกคนจะสามารถดูรายละเอียดเงินเดือนของพนักงานได้ คุณไม่ต้องการสิ่งนั้น 

เพื่อหลีกเลี่ยงปัญหานี้คุณอาจออกแบบคลาส DTO ที่ชื่อ EmployeeDTO ซึ่งจะมีเฉพาะคุณสมบัติที่ร้องขอเท่านั้น (เช่น Id, FirstName, LastName และ Department Name)

สร้างคลาส DTO ใน C #

เพื่อให้บรรลุสิ่งนี้ให้สร้างไฟล์ชื่อ EmployeeDTO.cs และเขียนโค้ดต่อไปนี้ในนั้น

ชั้นสาธารณะ EmployeeDTO

    {

        รหัส int สาธารณะ {get; ชุด; }

        สตริงสาธารณะ FirstName {get; ชุด; }

        สตริงสาธารณะ LastName {get; ชุด; }

        สตริงสาธารณะ DepartmentName {get; ชุด; }

    }

เมื่อมีคลาสอ็อบเจ็กต์โมเดลและการถ่ายโอนข้อมูลแล้วคุณอาจต้องการสร้างคลาสตัวแปลงที่มีสองวิธี: วิธีหนึ่งในการแปลงอินสแตนซ์ของคลาสโมเดลพนักงานเป็นอินสแตนซ์ของ EmployeeDTO และ (ในทางกลับกัน) อีกวิธีหนึ่งเพื่อแปลงอินสแตนซ์ ของ EmployeeDTO ไปยังอินสแตนซ์ของคลาส Employee model นอกจากนี้คุณยังสามารถใช้ประโยชน์จาก AutoMapper ซึ่งเป็นไลบรารีการแมปวัตถุกับวัตถุยอดนิยมเพื่อจับคู่ประเภทที่ต่างกันทั้งสองนี้ คุณสามารถอ่านเพิ่มเติมเกี่ยวกับ AutoMapper ได้ที่นี่

คุณควรสร้างรายการในชั้นบริการของแอปพลิเคชันของคุณและส่งคืนคอลเล็กชันกลับไปที่เลเยอร์การนำเสนอ

ความไม่เปลี่ยนรูปของ DTO

DTO หมายถึงการขนส่งข้อมูลจากชั้นหนึ่งของแอปพลิเคชันไปยังอีกชั้นหนึ่ง ผู้บริโภคของ DTO อาจสร้างขึ้นใน. NET / C # / Java หรือแม้แต่ JavaScript / TypeScript DTO มักจะถูกทำให้เป็นอนุกรมเพื่อให้สามารถเป็นอิสระจากเทคโนโลยีที่ใช้ในเครื่องรับ ในกรณีส่วนใหญ่ผู้รับข้อมูลไม่จำเป็นต้องแก้ไขข้อมูลนั้นหลังจากได้รับ - ควรเป็นอย่างยิ่ง!

นี่คือตัวอย่างคลาสสิกของความสำคัญของการไม่เปลี่ยนรูป และนั่นคือเหตุผลที่ DTO ควรไม่เปลี่ยนรูป!

มีหลายวิธีที่คุณสามารถใช้ DTO ที่ไม่เปลี่ยนรูปได้ใน C # คุณสามารถใช้ ReadOnlyCollection หรือชนิดคอลเลกชันที่ไม่เปลี่ยนรูปของเธรดที่ปลอดภัยที่มีอยู่ใน System.Collections. คุณสามารถใช้ประโยชน์จากประเภทบันทึกใน C # 9 เพื่อใช้ DTO ที่ไม่เปลี่ยนรูปได้เช่นกัน

การออกแบบที่ขับเคลื่อนด้วยโดเมนคาดว่าวัตถุโดเมนจะไม่เปลี่ยนรูปภายนอก นี่เป็นเหตุผลที่ดีที่จะทำให้ DTO ของคุณไม่เปลี่ยนรูปใช่ไหม

ความท้าทายในการทำให้เป็นอนุกรม DTO

คุณควรจะสามารถทำให้เป็นอนุกรม / แยกสาย DTO ได้อย่างราบรื่นเพื่อให้สามารถส่งต่อสายไฟได้ อย่างไรก็ตามในทางปฏิบัติคุณอาจต้องแก้ปัญหาการทำให้เป็นอนุกรมเมื่อทำงานกับ DTO คุณอาจมีเอนทิตีหรือโมเดลคลาสหลายตัวในแอปพลิเคชันในโลกแห่งความเป็นจริงและแต่ละคลาสอาจมีการอ้างอิงซึ่งกันและกัน

สมมติว่าคุณได้สร้างระบบการจัดการการเข้างานสำหรับพนักงานในองค์กรของคุณ โดยทั่วไปคุณอาจมีคลาสที่เรียกว่า Employee ในแอปพลิเคชันของคุณที่อ้างอิงคลาส User (กล่าวคือพนักงานคือผู้ใช้แอปพลิเคชัน) ซึ่งจะอ้างอิงคลาส Role คลาส Role อาจอ้างอิงคลาส Permission ซึ่งอาจอ้างอิงคลาส PermissionType และ PermissionGroup ตอนนี้เมื่อคุณจัดลำดับอินสแตนซ์ของคลาสพนักงานคุณจะต้องทำให้วัตถุเหล่านี้เป็นอนุกรมเช่นกัน เป็นเรื่องง่ายที่จะเห็นว่าในบางกรณีที่ซับซ้อนคุณอาจต้องต่อเนื่องหลายประเภท

นี่คือจุดที่การโหลดแบบขี้เกียจหรือการโหลดแบบอะซิงโครนัสเข้ามาช่วย นี่คือคุณลักษณะที่สามารถช่วยให้คุณโหลดเอนทิตีเมื่อถูกร้องขอเท่านั้น สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการโหลดแบบขี้เกียจคุณสามารถดูบทความของฉันเกี่ยวกับการเริ่มต้นแบบขี้เกียจใน C #

โดยทั่วไปออบเจ็กต์การถ่ายโอนข้อมูลจะไม่มีตรรกะทางธุรกิจ - มีเพียงข้อมูลเท่านั้น ความไม่เปลี่ยนรูปเป็นคุณสมบัติที่ต้องการเมื่อทำงานกับ DTO มีหลายวิธีที่คุณสามารถใช้ DTO ที่ไม่เปลี่ยนรูปได้ ฉันจะพูดคุยเพิ่มเติมเกี่ยวกับความไม่เปลี่ยนรูปใน C # ในโพสต์ภายหลังที่นี่

วิธีทำเพิ่มเติมใน ASP.NET Core:

  • วิธีจัดการข้อผิดพลาด 404 ใน ASP.NET Core MVC
  • วิธีใช้การฉีดการพึ่งพาในตัวกรองการดำเนินการใน ASP.NET Core 3.1
  • วิธีใช้รูปแบบตัวเลือกใน ASP.NET Core
  • วิธีใช้ endpoint Routing ใน ASP.NET Core 3.0 MVC
  • วิธีการส่งออกข้อมูลไปยัง Excel ใน ASP.NET Core 3.0
  • วิธีใช้ LoggerMessage ใน ASP.NET Core 3.0
  • วิธีส่งอีเมลใน ASP.NET Core
  • วิธีบันทึกข้อมูลไปยัง SQL Server ใน ASP.NET Core
  • วิธีกำหนดเวลางานโดยใช้ Quartz.NET ใน ASP.NET Core
  • วิธีการส่งคืนข้อมูลจาก ASP.NET Core Web API
  • วิธีจัดรูปแบบข้อมูลตอบกลับใน ASP.NET Core
  • วิธีใช้ ASP.NET Core Web API โดยใช้ RestSharp
  • วิธีดำเนินการ async โดยใช้ Dapper
  • วิธีใช้แฟล็กฟีเจอร์ใน ASP.NET Core
  • วิธีใช้แอ็ตทริบิวต์ FromServices ใน ASP.NET Core
  • วิธีทำงานกับคุกกี้ใน ASP.NET Core
  • วิธีการทำงานกับไฟล์คงที่ใน ASP.NET Core
  • วิธีใช้ URL Rewriting Middleware ใน ASP.NET Core
  • วิธีใช้การ จำกัด อัตราใน ASP.NET Core
  • วิธีใช้ Azure Application Insights ใน ASP.NET Core
  • การใช้คุณสมบัติ NLog ขั้นสูงใน ASP.NET Core
  • วิธีจัดการข้อผิดพลาดใน ASP.NET Web API
  • วิธีใช้การจัดการข้อยกเว้นส่วนกลางใน ASP.NET Core MVC
  • วิธีจัดการค่า null ใน ASP.NET Core MVC
  • การกำหนดเวอร์ชันขั้นสูงใน ASP.NET Core Web API
  • วิธีการทำงานกับบริการของผู้ปฏิบัติงานใน ASP.NET Core
  • วิธีใช้ Data Protection API ใน ASP.NET Core
  • วิธีใช้มิดเดิลแวร์แบบมีเงื่อนไขใน ASP.NET Core
  • วิธีการทำงานกับสถานะเซสชันใน ASP.NET Core
  • วิธีเขียนคอนโทรลเลอร์ที่มีประสิทธิภาพใน ASP.NET Core