บันทึก Migrate .NET Framework > .NET6

Blog นี้เขียนดองมานานมาก ตั้งแต่กลางปีที่แล้ว แล้วค้างไปทำเรื่องอื่นๆ ตอนนี้จะเปิดตัว .NET8 แล้ว ถ้ารออีก อาจจะได้แชร์ปีปลายปีหน้าแทน 555 เลยคิดว่า เขียนให้หมดดีกว่า เดี๋ยวลืม

Stage แรก เป็นส่วนของการเริ่มต้นเลย ตอนแรก Code มันจะยุ่งเหยิงนิดนึง แยกให้เป็นส่วนๆ นอกจากจัดกลุ่มตาม DLL ผมเอาตัว Layer Architecture มาช่วยได้ โดยแบ่งหน้าที่ ต้องคุยตามชั้นจากบน ลงล่าง ซึ่งมีรายละเอียดดังนี้

Stage1

  • Presentation เป็นส่วนที่ต้อง Interact กับ ผู้ใช้ ไม่ว่าจะเป็น
    - WinApp
    - Office-AddIns (VSTO)
    - ASP.NET Web (API) - อันนี้ง่ายหน่อย เพิ่งขึ้นมา ของเดิมเป็น .NET WCF เลยแปลงมาซะ จะได้จัดการได้สะดวก เพราะ WCF ช้า และมีอะไรจุจิกใช้ REST แบบทั่วไปดีกว่า

แยก Logic ที่มันมั่วๆ มาปน UI Code-Behide / Controller มาแตกเป็น Service / Data Access และ DTO

  • Service - ส่วน Business Logic ตามแต่ละ Domain ถ้ามีจัดการกับ Database / IO / WebService ให้ตัว Data Access จัดการ
  • Data Access - ส่วนที่จัดการกับ Data หลัก พวกที่ต่อ Database แยกมาแล้วให้ ORM อย่างผมใช้ Dapper เพราะยังมี Legacy ที่ยังต้องจับ DB เดียวกันอยู่
  • Data Transfer Object (DTO) - เป็นชั้นพิเศษ ทำหน้าที่ห่อข้อมูล และส่งไปมาระหว่างแต่ละ Layer

ตอนทำแรกจะเป็น .NET Framework 4.5 กว่าจะทำเสร็จใช้ไปสักพัก ขยับเป็น .NET Framework 4.7.2 แล้ว อีกเรื่องที่ควรทำ เรื่อง Automate Test มีตั้งต้นไปบ้างแล้ว

Stage2

Ref: Cross-platform targeting for .NET libraries - .NET | Microsoft Learn

ต่อมาได้ข่าวเรื่อง NET Core ที่มัน Run บน Linux ได้ ตอนที่ได้ข่าวว่า Microsoft จะออกตัว NET Core มาสิ่งแรกที่ทำเลย โชคดีที่เลือกแบบ Layer Artitechture ไว้ เลยยกตัว

  • Service / Data Access / DTO ไปเป็น .NET Standard ก่อน
  • ตัว WebAPI ที่ยังเล็กอยู่ ตัดสินใจไป .NET Core 1-2 เลย เล็กๆ เจ็บน้อยๆ Breaking เยอะ ตอนมา .NET Core 3.1 5555
Stage 2

ถ้าสังเกตุจากรูป Stage2 มันมีตัวกล่อง Pipe ขึ้นมา อันนี้จะมาแก้ปัญหาของ VB6 ไม่อยากทำเพิ่มแล้ว พยายามให้ PIPE มาช่วยคุยระหว่าง VB6 - .NET

Issue ที่ต้องระวังจาก Stage 1 > Stage 2

  • ตรวจสอบ Dependecy ให้เรียบร้อยกว่า ว่ามันมีตัวที่ Compatible กับ .NET Standard แล้ว หรือยัง แต่ใน Stage นี้ส่วนใหญ่ใช้งานได้อยู่แล้วนะ ของผมจะรอตัว Dapper อย่าง + Test กับ DB2 ก่อนค่อยทำต่อ ตอนนี้จะข้อจำกัดแล้ว WebAPI และกลุ่ม WinApp / Office AddIns / Pipe ต้องแยก Driver DB2 ครับ มันคนละ Framework แล้ว
  • ตอนย้ายจะเจอพวก NuGet หลายๆตัว เช่น MoreLinq ที่แยกตัวออกไป ตอนนี้ถูกรวมเข้ามาใน .NET Standard แล้ว ตอนนี้มาไล่เอาออก และเปลี่ยน Reference ให้ถูก
  • สำหรับ csproject ผมสร้าง project เปล่าๆไว้ แล้วมันจะดึงเข้ามาเอง
    Note จริงๆมันมัน Tools Migrate นะ พอ Project เยอะๆมันจะเอ๋อๆ แล้วชอบแถมอะไรแปลกๆมาให้
  • Automate Test สำคัญนะ ที่เจอ Method บางทีมันปรับ
    - ของเดิม แยก NuGet ทำได้
    - ของใหม่ พอเอามารวมใน .NET Standard แล้วพฤติกรรมเปลี่ยนไปเล็กน้อย
    Unit Test จะมาช่วยตรงนี้แหละ

Stage3

Stage 3

ภาพสุดท้ายและ NET6 เปิดตัวตอนปี2021 แต่ที่ผมขยับทำช่วงกลางปีที่แล้ว โดยที่เริ่มได้ช้า เพราะตัว WinApp มี Issue หลายๆอย่างที่ยังไม่ขยับ .NET6 อาทิ เช่น

  • รอ Dependency
    - DevExpress กว่า DevExpress จะออกตัว NET6 สำหรับ Win App ช้าอยู่ แล้วเวอร์ชั้นแรก Bug กระจายครับ กว่าจะนิ่งได้รอนานอยู่
    Note: DevExpress ทำดีมาก Web ที่ List Issue Fixed / Breaking Change ของแต่ละ Product เวลาใช้ App มันตุย ต้องมาไล่หาในนี้
    - VSTO - ทาง Microsoft ประกาศแพเรียบร้อยเลย แล้วทำให้ภาพจาก
    > เดิม ที่ต่อเข้า Layer Service ตรง และส่ง Data ผ่านตัว DTO
    > ใหม่ ยังคง VSTO App ให้เป็น .NET Framework 4.7.2 ต่อไป ติดต่อดกับ WebAPI ผ่าน REST API แทนครับ
    อนาคต ต้องหาทาง Migrate จาก VSTO > Office Add-ins platform + JavaScript
  • และ API Change ของตัว NET เองอันนี้ใช้ตัว The .NET Portability Analyzer - .NET มาช่วย มันช่วยนะ อย่างพวก Globalization and ICU - .NET | Microsoft Learn เจอก่อนทยอยแก้ IndexOf, StartsWith, EndsWith, Contains, ToUpper, ToLower, ToString เมื่อเครื่องที่ลงกำหนด Regional เป็นไทย
  • Upgrade Assistant - ลองได้นะ สำหรับ project เล็ก แต่ Project ใหญ่ๆไม่ค่อย Work ผมใช้ท่าเดียวกับ Stage1 > Stage2 สร้าง csproj เปล่าๆ ขึ้นมาคู่กัน และลบของเดิมออก

Issue ที่ต้องระวังจาก Stage 2 > Stage 3

  • Automate Test พัง อันนี้เกิดจากงานเร่ง และ Non IT ที่ไม่ได้เข้าใจถึงคุณค่า อันนี้แปลกเหมือนกัน คุยส่วนตัวไม่ได้
    ทางแก้ โพส Facebook ความสนใจมานิดนึง 555
  • Default JSON ASP.NET มันจะ Default System.Text.Json Namespace ของผมใช้ค่าย Json.NET - Newtonsoft ตอน Test จะเจอเคส Deseralize ไม่ได้
  • BinaryFormatter - MS เค้าจะยกเลิกใน NET8 ต้องหาทาง Migrate แล้วที่นี้จะมี Pattern Code ที่ดีในยุคนึง
    - NET Framework แบบที่แนะนำ ICloneable / MemberwiseClone หรือ new ใหม่แล้วใช้ Refection Copy แปะเอา แต่ทว่ามี Stack Overflow แนะนำลองใช้ BinaryFormatter สิ ที่นี้ Code งอกยาว
    - NET5 ++ ไม่ให้ใช้ มัน มี Issue ด้าน Security Breaking change: BinaryFormatter serialization methods are obsolete and prohibited in ASP.NET apps - .NET | Microsoft Learn
    ทางแก้
    - ไปใช้พวก AlenToma/FastDeepCloner: FastDeepCloner + JSON Serialize แก้ปัญหาไปก่อน
    - จากนั้นขยับไปใช้พวก MessagePack ใช้กับพวก SignalR ได้ด้วยนะ
    Note:
    - จริงๆตัว MessagePack มันอะไรคล้ายๆกับ BinaryFormatter แต่ทว่า ถ้า Object ใหญ่ และลึก ไม่ Work นะ
    - มีตัว ProtoBuff ที่น่าสนใจด้วยนะ
  • NET6 Minimal API และปรับพวก Style การเขียนระดับนึง ตอนนี้ยังไม่เชี่ยว 5555
  • DB2 - ตัวแสบเลย .NET Framework > NET5 / NET6 พี่แกเล่นแก้ Namespace ตามเวอร์ชันเลย 55555
    Ref: DB2 Driver งงไปหมดด | naiwaen@DebuggingSoft
  • Reporting ของเดิมใช้ Crystal Report เก่าระดับนึงเลยแหละปี 2013 ถ้าย้ายมาต้องซื้อ
    ทางแก้ ทยอย Migrate ไปใช้ DevExpess Report แทน ทำมาตั้งแต่ Stage 2
  • Logging ตอนแรกตัว Slf4net + Log4Net มันไม่เขียน Log และไม่บิ้มด้วย ต้องมาทำตัว Resolver แล้ว Add เพิ่มเข้าไป
  • Dependency Injection ผมยังไม่ได้ย้ายมานะ ยังใช้ Castle.Core อยู่ มันรื้อเยอะ แต่ฝั่ง Test + Project ใหม่ๆ ทยอยทำแล้ว
  • Platform [X86/ ARM] + OS [Windows /Mac / Linux] ต้องหาทางแก้กัน DB2 ตัวอย่างนึงในนั้น
    Ref: [.NET] บันทึกการจัดการ NuGet ที่ต้องแยกเฉพาะตาม Platform ครับ | naiwaen@DebuggingSoft
  • PIPE ใน .NET6.0 เป็นต้นไป namedpipeserverstream ต้องสร้างจาก namedpipeserverstreamacl
  • Build System แยก Agent
    - Windows พวก WinApp / Office-AddIns / PIPE
    - Linux พวก WebAPI
  • การประสานงาน เรื่องคนล้วนๆ จากการขยับจาก .NET Framework 4.7.2 > NET6 มันลง Runtime ใหม่ ด้วย Solution ที่มี Win App อยู่ พร้อมกับ Client
    - รอบนี้ ผม Hold ไว้นานมาก ประมาณ 10 เดือน ++ ให้ทาง Support คุยกับลูกค้าให้พร้อม หรือ ไปคุยเองให้ ระหว่างนี้ปวดหัวเรื่อง Merge พอสมควรเลย เพราะต้อง Maintain Branch develop (NET6) และ support/net472 (.NET Framework 4.7.2)
    - ซึ่งจะต่างรอบใน Stage 2 ที่มันยังไม่ Breaking Change เยอะ ให้เวลาไป Support 3 เดือน

Bonus: ASP.NET Web Form

เห็นมีคนถามพวก ASP.NET Web Form นะครับ

  • กำจัด Web Form เปิด API ขึ้นมาก่อน แล้วทำส่วน Web Form ไปเป็นตัวอื่น เช่น Vue / Angular / React (ของผม ทีมเลือก Angular)
  • ตอนแยก API ช่วงแรกอาจจะยังเป็น .NET Framework ขยับสูงสุดที่มี .NET Framework 4.8 ผมถึง Step นี้นะ
  • ที่เหลือ แล้วแต่ตาม Step WebAPI ที่เขียนแล้วครับ ระหว่างนี้ ถ้าตัว WebForm ยังอยู่ใช้ตัว Reverse Proxy YARP (microsoft.github.io) หรือ Nginx มาช่วยในการทยอย Migrate ครับ ส่วนตัวเล่น Demo ยังไม่ได้ลองงานจริง

สรุปจะย้ายอะไรดู Dependency / Test / และ Release Plan

เขียนไปเขียนมา เป็น Architecture Evolution ในช่วง 5-6 ปีเลย จริงๆมีอีกหลายเรื่อง บางทีแก้ไปแล้วลืมจดไว้ 555

Reference


Discover more from naiwaen@DebuggingSoft

Subscribe to get the latest posts sent to your email.