Bài 9: Serialization - Nền tảng lập trình C#


Serialize có nghĩa là sắp theo thứ tự. Khi ta muốn lưu một đối tượng xuống tập tin trên đĩa để lưu trữ, ta phải định ra trình tự lưu trữ của dữ liệu trong đối tượng. Khi cần tái tạo lại đối tượng từ thông tin trên tập tin đã lưu trữ, ta sẽ nạp đúng theo trình tự đã định trước đó. Đây được gọi là quá trình Serialize.


  • Kỹ thuật chuyển đổi với BinaryFormatter
  • Kỹ thuật chuyển đổi với XmlSerializer
  • Kỹ thuật chuyển đổi lớp đối tượng thông qua lớp giao tiếp ISerializable

Serialization

  • Nhiều ứng dụng cần lưu trữ và trao đổi dữ liệu được lưu trong các đối tượng với nhau
  • Serialization (chuyển đổi) : là tiến trình biến đổi và tái tạo các đối tượng để chúng có thể được lưu trữ và trao đổi giữa các ứng dụng
  • .NET framework cung cấp nhiều kỹ thuật chuyển đổi để đơn giản hóa tác vụ này

1. Kỹ thuật chuyển đổi với BinaryFormatter

  • Serialize
    • Tiến trình chuyển một đối tượng thành chuỗi tuần tự các byte để có thể lưu trữ hoặc trao đổi.
    • Các bước thực hiện
      • Tạo đối tượng Stream lưu kết quả chuyển đổi
      • Tạo đối tượng BinaryFormatter
      • Gọi phương thức BinaryFormatter.Serialize để chuyển đổi, lưu kết quả vào Stream

Kỹ thuật chuyển đổi với BinaryFormatter

  • Deserialize
    • Tiến trình chuyển chuỗi tuần tự các byte thu được từ quá trình serialize thành đối tượng ban đầu
    • Các bước thực hiện
      • Tạo Stream đọc kết quả của quá trình serialize
      • Tạo đối tượng BinaryFormatter
      • Tạo đối tượng lưu dữ liệu sau khi chuyển đổi
      • Gọi phương thức BinaryFormatter.Deserialize để chuyển đổi lại và ép kiểu phù hợp với kiểu của đối tượng ban đầu

 Demo deserialize Kỹ thuật chuyển đổi với BinaryFormatter

Tạo lớp có thể serialize

  • Thêm thuộc tính Serializable vào lớp cần chuyển đổi, .NET framework sẽ tự động serialize.
  • Có thể kiểm soát quá trình serialize của các lớp để tăng hiệu quả / đáp ứng các yêu cầu của ứng dụng
[Serializable]
public class ShoppingCartItem
{
   public int productId;
   public decimal price;
   public int quantity;
   public decimal total;
}

Vô hiệu hóa chuyển [Serializable] đổi các thành phần của lớp

  • Những giá trị tạm, thuộc tính tính toán
  • Thêm thuộc tính NonSerialized trước khai báo
  • Thành phần NonSerialized không được khởi tạo khi deserialize

Tự động khởi tạo các thành phần NonSerialized khi deserialize:

  • Thực thi interface IDeserializationCallback
  • Thực thi phương thức IDeserializationCallback.OnDeSerialization
[Serializable]
public class ShoppingCartItem : IDeserializationCallback{
….
    [NonSerialized] public decimal total;
    public ShoppingCartItem(int _procId,decimal _price,int _quan){
    …
       total=price+quantity;
    }
    void IDeserializationCallback.OnDeserialization(object sender){
       total=price*quantity;
    }
}

Tương thích phiên bản

  • Phát sinh ngoại lệ khi deserialize đối tượng được serialize ở phiên bản trước của ứng dụng
    • Thêm thành phần mới vào lớp, deserialize đối tượng được serialize trước đó mà không có thành phần mới
  • Giải pháp:
    • Thực thi custom serialization
    • Thêm thuộc tính OptionalField trước thành phần mới có thể gây không tương thích phiên bản
  • Thành phần OptionalField không được khởi tạo khi deserialize

Chọn định dạng chuyển đổi

.NET Framework cung cấp 2 phương thức định dạng dữ liệu chuyển đổi:

  • BinaryFormatter: định dạng hiệu quả nhất để serialize các đối tượng sẽ chỉ được hiểu bởi á các ứng dụng .NET
  • SoapFormatter:
    • định dạng , XML, là cách thức đáng tin cậy để serialize các đối tượng được trao đổi trên môi trường mạng/ được hiểu bởi các ứng dụng ngoài .NET
    • Có khả năng vượt tường lửa tốt hơn BinaryFormatter

2. Kỹ thuật chuyển đổi với XmlSerializer

  • XML : định dạng tài liệu văn bản chuẩn cho việc lưu trữ và trao đổi thông tin.
  • .NET Framework cung cấp nhiều thư viện hỗ trợ đọc, ghi file XML, chuyển đổi các đối tượng sang định dạng XML và ngược lại.
  • Tại sao sử dụng XML Serialization
    • Khả năng giao tiếp rộng
    • Thân thiện với người dùng, dễ dàng đọc và hiệu chỉnh
    • Khả năng tương thích phiên bản cao
  • Hạn chế của XML Serialization
    • Chỉ có thể chuyển đổi các dữ liệu public
    • Không thể chuyển đổi đối tượng đồ thị, biểu đồ

Serialize

Các bước thực hiện

  • Tạo đối tượng Stream/ TextWriter/ XmlWriter để lưu kết quả chuyển đổi
  • Tạo đối tượng XmlSerializer với kiểu của đối tượng cần chuyển đổi
  • Gọi phương thức XmlSerializer.Serialize để chuyển đổi và lưu kết quả

demo serializer Kỹ thuật chuyển đổi với XmlSerializer

Deserialize

Các bước thực hiện

  • Tạo đối tượng Stream/ TextWriter/ XmlWriter để đọc kết quả chuyển đổi của quá trình serialize • Tạo đối tượng XmlSerializer với kiểu của đối tượng cần chuyển đổi
  • Gọi phương thức XmlSerializer.Deserialize để tái tạo đối tượng ban đầu, ép kiểu dữ liệu cho phù hợp

demo Deserialize Kỹ thuật chuyển đổi với XmlSerializer

Tạo lớp có thể serialize

Khi chuyển đổi các lớp đáp ứng yêu cầu Xml serialization nhưng không có bất kỳ thuộc tính Xml Serialization nào, .NET sẽ dùng định dạng mặc định có để đáp ứng yêu cầu của nhiều người dùng.

  • Tên của Xml element : phụ thuộc vào tên lớp và tên thành phần
  • Mỗi thành phần được chuyển đổi thành một Xml element riêng biệt

Tạo lớp có thể chuyển đổi xmlserializer

Tạo lớp có thể chuyển đổi

  • Nếu chỉ tạo tài liệu XML mô tả lớp kết quả quá trình chuyển đổi được coi là đủ
  • Nếu muốn tạo tài liệu XML đáp ứng những yêu cầu cụ thể: can thiệp vào quá trình chuyển đổi tài liệu XML có định dạng theo yêu cầu

Tạo lớp có thể chuyển đổi xmlserializer

Custom Serialization

  • Kỹ thuật chuyển đổi lớp đối tượng thông qua lớp giao tiếp ISerializable
  • Tiến trình điều khiển việc chuyển đổi và tái tạo đối tượng, đảm bảo tương thích phiên bản
  • Thực thi custom serialization
    • Serialize trong .NET rất uyển chuyển và có thể tùy biến để đáp ứng yêu cầu phát triển ứng dụng.
    • Có thể override quá trình serialize xây dựng sẵn trong ằ .NET bằng cách thực thi interface Iserializable và khai báo thuộc tính Serializable cho lớp.
    • Thực thi interface Iserializable sẽ gọi
      • Phương thức GetObjectData trong quá trình serialize
      • Phương thức khởi tạo đặc biệt trong quá trình deserialize

Ví dụ Custom Serialization

Các sự kiện trong Serialization

  • Serializing: phát sinh trước khi serialize bắt đầu
    • Thêm thuộc tính OnSerializing trước phương thức
  • Serialized: phát sinh sau khi serialize hoàn tất
    • Thêm thuộc tính OnSerialized trước phương thức
  • Deserializing: phát sinh trước khi deserialize bắt đầu
    • Thêm thuộc tính OnDeserializing trước phương thức
  • Deserialized: phát sinh sau khi serialize kết thúc
    • Thêm thuộc tính OnDeserialized trước phương thức

Các sự kiện trong Serialization

Các sự kiện trong serialization

Các sự kiện trong Serialization

  • Các sự kiện này là cách tốt nhất và dễ dàng nhất để điều khiển tiến trình chuyển đổi
    • Không can thiệp vào serialization stream
    • Cho phép hiệu chỉnh đối tượng trước và sau serialize
  • Yêu cầu cho các phương thức xử lý các sự kiện
    • Có tham số là đối tượng StreamingContext
    • Không trả về kết quả

Thay đổi ngữ cảnh chuyển đổi

  • Khi serialize 1 đối tượng: không cần quan tâm đích đến
  • Trong vài trường hợp: serialize và deserialize sẽ khác nhau phụ thuộc vào đích đến
  • Cấu trúc StreamingContext cung cấp thông tin đích đến của đối tượng được serialize cho lớp xử lý thực thi interface Iserializable
    • StreamingContext có 2 thuộc tính:
      • Context: tham chiếu đến đối tượng chứa thông tin ngữ cảnh
      • state: 1 tập cờ hiệu chỉ ra nguồn đích của đối tượng đang serialize và deserialize

Các cờ hiệu của thuộc tính State

  • CrossProcess
  • CrossMachine
  • File
  • Persistence
  • Remoting
  • Other
  • Close
  • CrossAppDomain
  • All

Bài viết tiếp theo

Chia sẽ bài viết :