This library is a extension that help your use Google Protobuf without .proto
files.
In general .proto
file will generate model that inherit IMessage
.
Protobuf using it for serialization.
Sometimes we already have some models in .NET projects and doesn't need to share them for other languages. And we also need to serialize or deserialize them with Protobuf.
In this case, this library will help you to use Protobuf for serialization.
Wodsoft.Protobuf.Wrapper requires NETStandard 2.0 or above.
The library works on platform that allow dynamic complie. For example, IOS is not allow to work.
Library is available in NuGet package Wodsoft.Protobuf.Wrapper.
dotnet add package Wodsoft.Protobuf.Wrapper
You can use method Serialize
of Wodsoft.Protobuf.Message
.
You need a System.IO.Stream
to store bytes.
YourModel model = new ();
MemoryStream stream = new MemoryStream();
Message.Serialize(stream, model);
Also, there is a overloaded method.
You can pass a Google.Protobuf.CodedInputStream
from your context.
YourModel model = new ();
CodedInputStream input = ...;
Message.Serialize(input, model);
Or you want to serialize to bytes directly.
YourModel model = new ();
var bytes = Message.SerializeToBytes(model);
You can use method Deserialize
of Wodsoft.Protobuf.Message
.
You need a System.IO.Stream
where contains serialized bytes.
Then it will return your model of generic argument T
.
Stream stream = ...;
YourType model = Message.Deserialize<YourType>(stream);
Also, there is a overloaded method too.
You can pass a Google.Protobuf.CodedOutputStream
from your context.
CodedOutputStream output = ...;
YourType model = Message.Deserialize<YourType>(output);
Or you want to deserialize from bytes directly.
YourType model = Message.DeserializeFromBytes<YourType>(bytes);
IMessageFieldProvider.GetFields(Type type)
will return message fields that map from a object type.
The default implementation is GeneralMessageFieldProvider.Intance
.
It's only map readable and writeable propertie to message field.
You can create your own IMessageFieldProvider
to map message fields.
And set Message<T>.FieldProvider
to your field provider instance value.
Use System.Runtime.Serialization.DataMemberAttribute
for your properties and set the Order
property to attribute.
Otherwise it will order properties with name.
⚠️ If there is aDataMemberAttribute
on any property, it will ONLY serialize or deserialize with properties which hasDataMemberAttribute
.
⚠️ If there is noDataMemberAttribute
exists, communication with difference version model program maybe FAULT because of difference property ORDER.
Use MessageBuilder.SetTypeInitializer<T>(Func<T> initializer)
to set the initializer for non empty parameter constructor object.
We can set a model value to Message<>
variable directly.
SimplyModel model;
Message<SimplyModel> message = model;
Then message
can be used in Protobuf serialization directly.
C# Types | Protobuf Types | Message Structure |
---|---|---|
bool(?) | bool | Varint |
sbyte(?) | int32 | Varint |
byte(?) | int32 | Varint |
short(?) | int32 | Varint |
ushort(?) | int32 | Varint |
int(?) | int32 | Varint |
long(?) | int64 | Varint |
uint(?) | uint32 | Varint |
ulong(?) | uint64 | Varint |
float(?) | float | Varint |
double(?) | double | Varint |
decimal(?) | ByteString | Length-delimited |
string | string | Length-delimited |
byte[] | ByteString | Length-delimited |
Guid(?) | ByteString | Length-delimited |
DateTime(?) | google.protobuf.Timestamp | Length-delimited |
DateTimeOffset(?) | google.protobuf.Timestamp | Length-delimited |
TimeSpan(?) | google.protobuf.Duration | Length-delimited |
IMessage | Length-delimited | |
T[] | RepeatedField<T> | Length-delimited |
ICollection<T> | RepeatedField<T> | Length-delimited |
Collection<T> | RepeatedField<T> | Length-delimited |
IList<T> | RepeatedField<T> | Length-delimited |
List<T> | RepeatedField<T> | Length-delimited |
IDictionary<TKey, TValue> | MapField<TKey, TValue> | Length-delimited |
Dictionary<TKey, TValue> | MapField<TKey, TValue> | Length-delimited |
- (?) means work with
Nullable<>
types. - It's fine to use Protobuf object that inherit
Google.Protobuf.IMessage
as property type. - All
RepeatedField
andMapField
object CAN NOT CONTAINSnull
values. - We support use
byte
,sbyte
,short
andushort
as property type. It will work as typeint
with serialization. Deserialize from other library serialized message,int
field maybe lost its data.
Mainly, Protobuf do serialization through Google.Protobuf.IMessage
and Google.Protobuf.IBufferMessage
interfaces.
So we define a abstract Wodsoft.Protobuf.Message
class.
And define protected abstract Read
, Write
, CalculateSize
methods.
Explicit implement there interfaces and call the methods.
Then define a abstract Wodsoft.Protobuf.Message<T>
generic class.
There is a property to reach origin model. And we can make some implicit operator here.
public T Source { get; }
Finally, we create dynamic class inherit Message<T>
for those models when they need to do serialization in runtime.
Emit codes for Read
, Write
, CalculateSize
.
- RECOMMEND USE
RepeatedField<>
,IList<>
orICollection<>
as collection property type. UseRepeatedField<>
will be the fastest performance. - Use
IList<>
orICollection<>
will convert it toRepeatedField<>
when serialize model. - Use
List<>
orCollection<>
will convert it toRepeatedField<>
when serialize model. And convert it back when deserialize model. - RECOMMEND USE
MapField<,>
orIDictionary<,>
as dictionary property type. UseMapField<,>
will be the fastest performance. - Use
IDictionary<,>
will convert it toMapField<,>
when serialize model. - Use
Dictionary<,>
will convert it toMapField<,>
when serialize model. And convert it back when deserialize model.
This library is under the MIT License.