Skip to content

Commit 556ae55

Browse files
committed
Change namespace
1 parent afc365f commit 556ae55

14 files changed

+230
-24
lines changed

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 Kation
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+180
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# Wodsoft Protobuf Wrapper
2+
3+
## Contents
4+
5+
- [About](#About)
6+
- [Requirements]
7+
- [Installation]
8+
- [Usage]
9+
- [Serialize]
10+
- [Deserialize]
11+
- [Field order]
12+
- [Get Protobuf Wrapper]
13+
- [Advanced]
14+
- [Supported property types and relationships]
15+
- [How it works]
16+
- [Performance]
17+
- [License]
18+
19+
## About
20+
21+
This library is a extension that help your use Google Protobuf without `.proto` files.
22+
23+
In general `.proto` file will generate model that inherit `IMessage`.
24+
Protobuf using it for serialization.
25+
26+
Sometimes we already have some models in .NET projects and doesn't need to share them for other languages.
27+
And we also need to serialize or deserialize them with Protobuf.
28+
29+
In this case, this library will help you to use Protobuf for serialization.
30+
31+
## Requirements
32+
33+
Wodsoft.Protobuf.Extensions requires NETStandard2.0 or above.
34+
35+
The library works on platform that allow dynamic complie. For example, **IOS is not allow to work.**
36+
37+
## Installation
38+
39+
Library is available in four NuGet packages.
40+
41+
```bash
42+
dotnet add package Wodsoft.Protobuf.Wrapper
43+
```
44+
45+
## Usage
46+
47+
### Serialize
48+
49+
You can use method `Serialize` of `Wodsoft.Protobuf.Message`.
50+
You need a `System.IO.Stream` to store bytes.
51+
52+
```csharp
53+
YourModel model = new ();
54+
MemoryStream stream = new MemoryStream();
55+
Message.Serialize(stream, model);
56+
```
57+
58+
Also, there is a overloaded method.
59+
You can pass a `Google.Protobuf.CodedInputStream` from your context.
60+
61+
```csharp
62+
YourModel model = new ();
63+
CodedInputStream input = ...;
64+
Message.Serialize(input, model);
65+
66+
```
67+
68+
### Deserialize
69+
70+
You can use method `Deserialize` of `Wodsoft.Protobuf.Message`.
71+
You need a `System.IO.Stream` where contains serialized bytes.
72+
Then it will return your model of generic argument `T`.
73+
74+
```csharp
75+
Stream stream = ...;
76+
YourType model = Message.Deserialize<YourType>(stream);
77+
```
78+
79+
Also, there is a overloaded method too.
80+
You can pass a `Google.Protobuf.CodedOutputStream` from your context.
81+
82+
```csharp
83+
CodedOutputStream output = ...;
84+
YourType model = Message.Deserialize<YourType>(output);
85+
```
86+
87+
### Field order
88+
89+
Use `System.Runtime.Serialization.DataMemberAttribute` for your properties and set the `Order` property to attribute.
90+
91+
**Important:** If there is a `DataMemberAttribute` on any property, it will only serialize or deserialize with properties which has `DataMemberAttribute`.
92+
93+
### Get Protobuf Wrapper
94+
95+
We can set a model value to `Message<>` variable directly.
96+
97+
```csharp
98+
SimplyModel model;
99+
Message<SimplyModel> message = model;
100+
```
101+
102+
Then `message` can be used in Protobuf serialization directly.
103+
104+
105+
## Advanced
106+
107+
### Supported property types and relationships
108+
109+
| C# Types | Protobuf Types | Message Structure |
110+
| - | - | - |
111+
| bool(?) | bool | Varint |
112+
| sbyte(?) | int32 | Varint |
113+
| byte(?) | int32 | Varint |
114+
| short(?) | int32 | Varint |
115+
| ushort(?) | int32 | Varint |
116+
| int(?) | int32 | Varint |
117+
| long(?) | int64 | Varint |
118+
| uint(?) | uint32 | Varint |
119+
| ulong(?) | uint64 | Varint |
120+
| float(?) | float | Varint |
121+
| double(?) | double | Varint |
122+
| string | string | Length-delimited |
123+
| byte[] | ByteString | Length-delimited |
124+
| Guid(?) | ByteString | Length-delimited |
125+
| DateTime(?) | google.protobuf.Timestamp | Length-delimited |
126+
| DateTimeOffset(?) | google.protobuf.Timestamp | Length-delimited |
127+
| TimeSpan(?) | google.protobuf.Duration | Length-delimited |
128+
| IMessage | | Length-delimited |
129+
| T[] | RepeatedField\<T\> | Length-delimited |
130+
| ICollection\<T\> | RepeatedField\<T\> | Length-delimited |
131+
| Collection\<T\> | RepeatedField\<T\> | Length-delimited |
132+
| IList\<T\> | RepeatedField\<T\> | Length-delimited |
133+
| List\<T\> | RepeatedField\<T\> | Length-delimited |
134+
| IDictionary\<TKey, TValue\> | MapField\<TKey, TValue\> | Length-delimited |
135+
| Dictionary\<TKey, TValue\> | MapField\<TKey, TValue\> | Length-delimited |
136+
137+
- **(?)** means work with `Nullable<>` types.
138+
- It's fine to use Protobuf object that inherit `Google.Protobuf.IMessage` as property type.
139+
- All `RepeatedField` and `MapField` object **CAN NOT CONTAINS** `null` values.
140+
- We support use `byte`, `sbyte`, `short` and `ushort` as property type.
141+
It will work as type `int` with serialization.
142+
Deserialize from other library serialized message, `int` field maybe lost its data.
143+
144+
### How it works
145+
146+
Mainly, Protobuf do serialization through `Google.Protobuf.IMessage` and `Google.Protobuf.IBufferMessage` interfaces.
147+
148+
So we define a abstract `Wodsoft.Protobuf.Message` class.
149+
And define protected abstract `Read`, `Write`, `CalculateSize` methods.
150+
Explicit implement there interfaces and call the methods.
151+
152+
Then define a abstract `Wodsoft.Protobuf.Message<T>` generic class.
153+
There is a property to reach origin model. And we can make some implicit operator here.
154+
```csharp
155+
public T Source { get; }
156+
```
157+
158+
Finally, we create dynamic class inherit `Message<T>` for those models when they need to do serialization in runtime.
159+
Emit codes for `Read`, `Write`, `CalculateSize`.
160+
161+
### Performance
162+
163+
It is nothing at performance cost in general types.
164+
But there is some performance cost when use some primitives types that Protobuf doesn't support.
165+
166+
- **RECOMMEND DO NOT USE** `byte`, `sbyte`, `short` and `ushort` as property type.
167+
Specially use with generic types like `List` or `Dictionary` etc.
168+
It will cost more **performance** for convert them from `int` to purpose type.
169+
- **RECOMMEND USE** `RepeatedField<>`, `IList<>` or `ICollection<>` as collection property type.
170+
Use `RepeatedField<>` will be the **fastest performance**.
171+
- Use `IList<>` or `ICollection<>` should convert it to `RepeatedField<>` when serialize model.
172+
- Use `List<>` or `Collection<>` should convert it to `RepeatedField<>` when serialize model.
173+
And convert it back when deserialize model.
174+
- **RECOMMEND USE** `MapField<,>` or `IDictionary<,>` as dictionary property type.
175+
Use `MapField<,>` will be the **fastest performance**.
176+
177+
178+
## License
179+
180+
This library is under the MIT License.

Wodsoft.Protobuf.Wrapper.sln

+18-13
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,38 @@ VisualStudioVersion = 16.0.30711.63
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{DD2E233C-A066-4350-9968-620393EFABB3}"
77
EndProject
8-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wodsoft.Protobuf.Extensions", "src\Wodsoft.Protobuf.Extensions\Wodsoft.Protobuf.Extensions.csproj", "{C2C5CE16-E231-4F6D-B803-E175013EE034}"
9-
EndProject
108
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{8130B4B4-54B1-4735-9F99-7E0A334FC1D8}"
119
EndProject
12-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wodsoft.Protobuf.Extensions.Test", "test\Wodsoft.Protobuf.Extensions.Test\Wodsoft.Protobuf.Extensions.Test.csproj", "{CC5A38A7-5946-4815-AF2C-FEB99FCAD4F7}"
10+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A2FE6DD1-807D-49C9-A3BB-7D5AD51FAF07}"
11+
ProjectSection(SolutionItems) = preProject
12+
README.md = README.md
13+
EndProjectSection
14+
EndProject
15+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wodsoft.Protobuf.Wrapper", "src\Wodsoft.Protobuf.Wrapper\Wodsoft.Protobuf.Wrapper.csproj", "{B21DAC30-4E80-476B-A67D-765F02205E95}"
16+
EndProject
17+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wodsoft.Protobuf.Wrapper.Test", "test\Wodsoft.Protobuf.Wrapper.Test\Wodsoft.Protobuf.Wrapper.Test.csproj", "{BC84D9ED-1889-452D-BF12-47ABE772381D}"
1318
EndProject
1419
Global
1520
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1621
Debug|Any CPU = Debug|Any CPU
1722
Release|Any CPU = Release|Any CPU
1823
EndGlobalSection
1924
GlobalSection(ProjectConfigurationPlatforms) = postSolution
20-
{C2C5CE16-E231-4F6D-B803-E175013EE034}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21-
{C2C5CE16-E231-4F6D-B803-E175013EE034}.Debug|Any CPU.Build.0 = Debug|Any CPU
22-
{C2C5CE16-E231-4F6D-B803-E175013EE034}.Release|Any CPU.ActiveCfg = Release|Any CPU
23-
{C2C5CE16-E231-4F6D-B803-E175013EE034}.Release|Any CPU.Build.0 = Release|Any CPU
24-
{CC5A38A7-5946-4815-AF2C-FEB99FCAD4F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25-
{CC5A38A7-5946-4815-AF2C-FEB99FCAD4F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
26-
{CC5A38A7-5946-4815-AF2C-FEB99FCAD4F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
27-
{CC5A38A7-5946-4815-AF2C-FEB99FCAD4F7}.Release|Any CPU.Build.0 = Release|Any CPU
25+
{B21DAC30-4E80-476B-A67D-765F02205E95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26+
{B21DAC30-4E80-476B-A67D-765F02205E95}.Debug|Any CPU.Build.0 = Debug|Any CPU
27+
{B21DAC30-4E80-476B-A67D-765F02205E95}.Release|Any CPU.ActiveCfg = Release|Any CPU
28+
{B21DAC30-4E80-476B-A67D-765F02205E95}.Release|Any CPU.Build.0 = Release|Any CPU
29+
{BC84D9ED-1889-452D-BF12-47ABE772381D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
30+
{BC84D9ED-1889-452D-BF12-47ABE772381D}.Debug|Any CPU.Build.0 = Debug|Any CPU
31+
{BC84D9ED-1889-452D-BF12-47ABE772381D}.Release|Any CPU.ActiveCfg = Release|Any CPU
32+
{BC84D9ED-1889-452D-BF12-47ABE772381D}.Release|Any CPU.Build.0 = Release|Any CPU
2833
EndGlobalSection
2934
GlobalSection(SolutionProperties) = preSolution
3035
HideSolutionNode = FALSE
3136
EndGlobalSection
3237
GlobalSection(NestedProjects) = preSolution
33-
{C2C5CE16-E231-4F6D-B803-E175013EE034} = {DD2E233C-A066-4350-9968-620393EFABB3}
34-
{CC5A38A7-5946-4815-AF2C-FEB99FCAD4F7} = {8130B4B4-54B1-4735-9F99-7E0A334FC1D8}
38+
{B21DAC30-4E80-476B-A67D-765F02205E95} = {DD2E233C-A066-4350-9968-620393EFABB3}
39+
{BC84D9ED-1889-452D-BF12-47ABE772381D} = {8130B4B4-54B1-4735-9F99-7E0A334FC1D8}
3540
EndGlobalSection
3641
GlobalSection(ExtensibilityGlobals) = postSolution
3742
SolutionGuid = {90755075-18FD-4047-82F1-5F2CA1B10019}

test/Wodsoft.Protobuf.Wrapper.Test/BuilderTest.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
using System.IO;
44
using Xunit;
55

6-
namespace Wodsoft.Protobuf.Extensions.Test
6+
namespace Wodsoft.Protobuf.Wrapper.Test
77
{
88
public class BuilderTest
99
{

test/Wodsoft.Protobuf.Wrapper.Test/CollectionModel.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
using System.Collections.ObjectModel;
44
using System.Text;
55

6-
namespace Wodsoft.Protobuf.Extensions.Test
6+
namespace Wodsoft.Protobuf.Wrapper.Test
77
{
88
public class CollectionModel
99
{

test/Wodsoft.Protobuf.Wrapper.Test/ContentModel.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using System.Collections.Generic;
33
using System.Text;
44

5-
namespace Wodsoft.Protobuf.Extensions.Test
5+
namespace Wodsoft.Protobuf.Wrapper.Test
66
{
77
public class ContentModel
88
{

test/Wodsoft.Protobuf.Wrapper.Test/DictionaryModel.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using System.Collections.Generic;
33
using System.Text;
44

5-
namespace Wodsoft.Protobuf.Extensions.Test
5+
namespace Wodsoft.Protobuf.Wrapper.Test
66
{
77
public class DictionaryModel
88
{

test/Wodsoft.Protobuf.Wrapper.Test/EnumModel.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using System.Collections.Generic;
33
using System.Text;
44

5-
namespace Wodsoft.Protobuf.Extensions.Test
5+
namespace Wodsoft.Protobuf.Wrapper.Test
66
{
77
public class EnumModel
88
{

test/Wodsoft.Protobuf.Wrapper.Test/MessageModel.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using System.Collections.Generic;
33
using System.Text;
44

5-
namespace Wodsoft.Protobuf.Extensions.Test
5+
namespace Wodsoft.Protobuf.Wrapper.Test
66
{
77
public class MessageModel
88
{

test/Wodsoft.Protobuf.Wrapper.Test/MessageTest.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
using System.Text;
55
using Xunit;
66

7-
namespace Wodsoft.Protobuf.Extensions.Test
7+
namespace Wodsoft.Protobuf.Wrapper.Test
88
{
99
public class MessageTest
1010
{

test/Wodsoft.Protobuf.Wrapper.Test/SerializationTest.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
using System.Text;
77
using Xunit;
88

9-
namespace Wodsoft.Protobuf.Extensions.Test
9+
namespace Wodsoft.Protobuf.Wrapper.Test
1010
{
1111
public class SerializationTest
1212
{

test/Wodsoft.Protobuf.Wrapper.Test/SimplyModel.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using System.Collections.Generic;
33
using System.Text;
44

5-
namespace Wodsoft.Protobuf.Extensions.Test
5+
namespace Wodsoft.Protobuf.Wrapper.Test
66
{
77
public class SimplyModel
88
{

test/Wodsoft.Protobuf.Wrapper.Test/UserModel.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using System.Collections.Generic;
33
using System.Text;
44

5-
namespace Wodsoft.Protobuf.Extensions.Test
5+
namespace Wodsoft.Protobuf.Wrapper.Test
66
{
77
public class UserModel
88
{

test/Wodsoft.Protobuf.Wrapper.Test/Wodsoft.Protobuf.Wrapper.Test.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
</ItemGroup>
3030

3131
<ItemGroup>
32-
<ProjectReference Include="..\..\src\Wodsoft.Protobuf.Extensions\Wodsoft.Protobuf.Extensions.csproj" />
32+
<ProjectReference Include="..\..\src\Wodsoft.Protobuf.Wrapper\Wodsoft.Protobuf.Wrapper.csproj" />
3333
</ItemGroup>
3434

3535
<ItemGroup>

0 commit comments

Comments
 (0)