Closed pleonex closed 7 months ago
Starting .NET 7.0 (so .NET 8.0) the order of the properties is deterministic (see this PR). However we still support .NET 6.0, so the issue would be there. However, the declared order could be problematic when using base types. Base type property always are returned last, which could not be desirable.
We could keep the BinaryIgnore
attribute and create an attribute like BinaryFieldOrder
to optionally define the order of the properties. If one property in a type specify it, every property should as well, so the order is clear. The order doesn't need to be incremental, for instance there could be a difference of 10 between on property and another, allowing for base types to define the property in the middle. For .NET 6.0 this attribute would be mandatory.
Goal
Description
The classes
DataReader
andDataWriter
are big and contain a lot of logic. I propose to clarify their responsibility to only handle primitive types andstring
. This includesbyte[]
and helper methods like writing padding as it's still integers / bytes.The logic to serialize / deserialize models / objects (
WriteUsingReflection
,ReadUsingReflection
) based on attributes on properties should be moved into a separate class. That code is similar to what aJsonSerializer
orBinaryFormatter
would do, so it should be different to the responsibility ofDataWriter
.Additionally, we can take this opportunity to improve the API so that:
Proposed solution
Some ideas to improve the design of the API, reduces the complexity, clarify implementation and fixes some of its issues:
BinarySerializer
andBinaryDeserializer
Serialize<T>(object)
,Serialize(Type, object)
andT Deserialize<T>()
,object Deserialize(Type)
DataWriter
/DataReader
will be only for primitive types + stringDataWriter
/DataReader
type.GetProperties
is not guaranteed to match the C# code fileOrder
to define the order to iterate properties.BinaryField(Order = x)
BinaryIgnore
attributeBinaryBoolean
attribute:ReadAs
andWriteAs
into a newUnderlyingType
UnderlyingType
mandatory so it's clear what type will be read/write.MakeRequiredTrueValue
andFalseValue
properties of typelong
instead ofobject
object
to read/write as string.BinaryEnum
attributeReadAs
andWriteAs
into a newUnderlyingType
Make propertyBy default use the underlying type defined in the enum.UnderlyingType
mandatory so it's clear what type will be read/write.BinaryForceEndianness
to justBinaryEndianness
DataWriter
/DataReader
Endianness
property that will forward the values to the underlying reader/writerThe concept is similar to the
IConverter<,>
concept. We could also consider being an implementation ofIConverter<IBinary, object>
andIConverter<object, IBinary>
but we would need the actual types as a parameter.Example
Deserializer:
Serializer:
Acceptance criteria
Status
Serializable
attributeBinaryBooleanAttribute
BinaryEnumAttribute
BinaryForceEndianness
Considerit won't work for most formats, useful for format sections / headers so no need of converters. It would be confusing for users.IConverter<T, IBinary>