#How to use
Serialization is the process of translating a data structure into a sequence of bytes. We can serialize both simple types and real-world object models, which are described as classes and are called business objects or entities, and meet the following conditions:
- serializable class contains a public constructor without parameters;
- each business object class is associated with
BusinessObjectId
— a unique integer identifier of theulong
type; - serializable class properties are public and have a mapping to
TagId
— a unique integer property identifier within the business object class (of typeulong
).
The BusinessObjectId
and TagId
matchings are done by annotating the data with attributes or using the Fluent API.
#Data Annotations
Attributes provide a powerful means for associating metadata or declarative information with the code and can be used to map class identifiers to properties of business objects. In case you have full control over the code, this approach may be the most preferable.
The following attributes are defined for this approach:
BusinessObjectIdAttribute
— sets the value of the unique identifier of the business object class (it is used during serialization and will be ignored for deserialization);TagIdAttribute
— sets the value of the unique property identifier within the class;DateTimeEncodingRuleAttribute
— is for properties with typesDateTime
andDateTimeOffset
and allows you to define an encoding rule (DateOnly, DateTime, DateTimeOffset);EnumAsStringAttribute
— is for properties with type enumeration (enum
) and sets the encoding rule as a string in UTF-8 encoding (the integer base data type is used by default);StringEncodingRuleAttribute
— is for properties with type string (string
), sets the encoding into which the text will be converted before encoding it (in case of a conversion error and if theSafeMode
mode is on, the data will be saved in UTF-8 encoding).
Let's choose a pass for access to social infrastructure objects as a real world object and describe its model in the form of the ExtraCityPass
class using attributes.
#Fluent API
It is not always possible for us to use the data annotation method using attributes and apply it to the required business object class, as a rule, this is due to the following factors:
- we need to work with an already existing class from someone else's assembly (for example, another developer);
- dynamic matching of
BusinessObjectId
andTagId
is required; - requirements of the information security policy of the enterprise.
In this case, we operate a business object class that at least has a public constructor without parameters and public properties:
To work with a business object class that does not have a data annotation, we must prepare declarative information using the BusinessObjectConfiguration
and PropertyConfiguration
classes, and pass it to the serializer instance using the AddBusinessObjectConfiguration()
method.
Using the GetProperty()
method of the BusinessObjectConfiguration
class, we get access to a chain of methods for configuring class properties, similar in functionality to data annotation attributes:
SetTagId()
;SetDateTimeEncodingRule()
;SetEnumAsString()
;SetStringEncodingRule()
.
Let's prepare and apply the same declarative information for our ExtraCityPass
class in an alternative way:
Using the SyncTags()
method of the BusinessObjectConfiguration
class, unique property identifiers are synchronized, perhaps this looks like a "crutch" and this functionality will be changed in the future.
#Examples
Let's demonstrate the operation of the binary serializer using the already defined classes ExtraCityPass1
and ExtraCityPass2
as an example, as well as the prepared declarative information contained in the conf2
variable. We initialize an instance of the ExtraCityPass1
class and fill it with sample data:
#Serialization
The data from the data
variable will be used for later examples.
#Deserialization to a business object class with data annotation using attributes
#Deserialization to an arbitrary class with preliminary application of declarative information
#Decoding serialized data in case the object structure is unknown
#Specialized string encodings
The binary serializer allows you to use specialized encodings (derived classes from the abstract System.Text.Encoding
) to convert public property data of the string
type, which is especially important for languages whose alphabets are not covered by ASCII characters and contain up to 40..45 characters . In addition, the use of specialized encodings can be considered as a means of protecting information.
The string encoding method can be set directly for a particular public string property using the parameter mode
:
- data annotation attribute
StringEncodingRuleAttribute
; - property setting method
SetStringEncodingRule()
Fluent API. The parametermode
is an enum of typeStringEncodingMode
and can take the following values: UTF8
— use UTF-8 encoding;UTF16LE
— use UTF-16 encoding with big endian;CodePage
- use the encoding with the code specified in the named argument of the data annotation attributeCodePage
or property setting method Fluent API;Numeric
— use 4-bit encoding with character support:1
,2
,3
,4
,5
,6
,7
,8
,9
,0
,*
,-
,.
,/
,:
, ' ' (space);Predefined
— use the encoding whose class instance is assigned to the property of the binary serializerDefaultCharacterEncoding
.
#Explicit indication of the encoding code
With the encoding mode StringEncodingMode.CodePage
, the serializer adds the code of the encoding used to each string property that is encoded in this way. In the event when a business object contains many of these properties, it might make sense to consider a usage of a predefined encoding.
An example of setting a property by data annotation method using attributes:
An example of setting a property using the means of Fluent API:
#Using a predefined encoding
This method may be the most economical in terms of the size of the serialized object. At the same time, it will be very difficult to decode string data stored in this way without a library with the necessary encoding.
Encoding and decoding properties of a string type in the mode StringEncodingMode.Predefined
assumes that the serializer already knows how to encode strings in this mode, and it is the only one, for example:
Setting a property using data annotation attributes:
Setting a property using the Fluent API: