-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #645 from SteveDunn/bson
Add Bson serialization
- Loading branch information
Showing
41 changed files
with
2,873 additions
and
94 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
docs/site/Writerside/topics/reference/MongoIntegrationHowTo.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Integration with MongoDB | ||
|
||
It is possible to use value objects (VOs) in MongoDB. | ||
|
||
To generate a converter (serializer), add the `Bson` conversion in the attribute, e.g. | ||
|
||
```c# | ||
[ValueObject<string>(conversions: Conversions.Bson)] | ||
public partial class Name | ||
{ | ||
public static readonly Name NotSet = new("[NOT_SET]"); | ||
} | ||
``` | ||
|
||
Now that the serializers are generated, you now need to register them. | ||
Vogen generates a static class named `RegisterBsonSerializersFor[NameOfProject]`. | ||
This static class has a static method named `TryRegister`, which registers the serializers if they're not already registered, e.g.: | ||
|
||
```C# | ||
BsonSerializer.TryRegisterSerializer(new CustomerIdBsonSerializer()); | ||
BsonSerializer.TryRegisterSerializer(new EnergyUsedBsonSerializer()); | ||
``` | ||
A [MongoDB example is included in the source](https://github.com/SteveDunn/Vogen/tree/main/samples/Vogen.Examples/SerializationAndConversion/MongoScenario). | ||
|
||
Below is a walkthrough of that sample. | ||
|
||
The sample uses MongoDB to read and write entities (a `Person`) to a MongoDB database in a testcontainer. | ||
Note that attributes on the value objects do not specify the BSON serializer; that is specified in global config in `ModuleInitializer.cs`: | ||
|
||
```c# | ||
[ValueObject] | ||
public readonly partial struct Age; | ||
|
||
[ValueObject<string>] | ||
public readonly partial struct Name; | ||
|
||
public class Person | ||
{ | ||
public Name Name { get; set; } | ||
public Age Age { get; set; } | ||
} | ||
``` | ||
|
||
This simple example registers the serializers manually: | ||
```C# | ||
BsonSerializer.RegisterSerializer(new NameBsonSerializer()); | ||
BsonSerializer.RegisterSerializer(new AgeBsonSerializer()); | ||
``` | ||
|
||
… but it could just as easily registered them with the generated register: | ||
```C# | ||
BsonSerializationRegisterForVogen_Examples.TryRegister(); | ||
``` | ||
|
||
(_replace `Vogen_Examples` with the name of *your* project_) | ||
|
||
Next, it adds a bunch of `Person` objects to the database, each containing value objects representing age and name, and then reads them back. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<ProjectConfiguration> | ||
<Settings> | ||
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> | ||
</Settings> | ||
</ProjectConfiguration> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<ProjectConfiguration> | ||
<Settings> | ||
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> | ||
</Settings> | ||
</ProjectConfiguration> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<ProjectConfiguration> | ||
<Settings> | ||
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> | ||
</Settings> | ||
</ProjectConfiguration> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
98 changes: 98 additions & 0 deletions
98
samples/Vogen.Examples/SerializationAndConversion/Mongo/MongoScenario.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
using System; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Bogus; | ||
using JetBrains.Annotations; | ||
using MongoDB.Bson; | ||
using MongoDB.Bson.Serialization; | ||
using MongoDB.Bson.Serialization.Attributes; | ||
using MongoDB.Bson.Serialization.Serializers; | ||
using MongoDB.Driver; | ||
using Testcontainers.MongoDb; | ||
|
||
namespace Vogen.Examples.SerializationAndConversion.Mongo; | ||
|
||
|
||
[ValueObject] | ||
public readonly partial struct Age; | ||
|
||
[ValueObject<string>] | ||
public readonly partial struct Name; | ||
|
||
[UsedImplicitly] | ||
public class Person | ||
{ | ||
[BsonId] | ||
public ObjectId Id { get; set; } | ||
public Name Name { get; set; } | ||
public Age Age { get; set; } | ||
} | ||
|
||
[UsedImplicitly] | ||
public class MongoScenario : IScenario | ||
{ | ||
public async Task Run() | ||
{ | ||
string runnerOs = Environment.GetEnvironmentVariable("RUNNER_OS"); | ||
|
||
bool isLocalOrLinuxOnGitHub = string.IsNullOrEmpty(runnerOs) || runnerOs == "Linux"; | ||
|
||
if (!isLocalOrLinuxOnGitHub) | ||
{ | ||
Console.WriteLine("Skipping because not running locally or on Linux on a GitHub action."); | ||
return; | ||
} | ||
|
||
MongoDbContainer container = new MongoDbBuilder().WithImage("mongo:latest").Build(); | ||
|
||
await container.StartAsync(); | ||
|
||
var client = new MongoClient(container.GetConnectionString()); | ||
|
||
var database = client.GetDatabase("testDatabase"); | ||
var collection = database.GetCollection<Person>("peopleCollection"); | ||
|
||
BsonSerializer.RegisterSerializer(new NameBsonSerializer()); | ||
BsonSerializer.RegisterSerializer(new AgeBsonSerializer()); | ||
|
||
// or, use the generated one for all value objects... | ||
// BsonSerializationRegisterForVogen_Examples.TryRegister(); | ||
|
||
var personFaker = new Faker<Person>() | ||
.RuleFor(p => p.Name, f => Name.From(f.Name.FirstName())) | ||
.RuleFor(p => p.Age, f => Age.From(DateTime.Now.Year - f.Person.DateOfBirth.Year)); | ||
|
||
foreach (Person eachPerson in personFaker.Generate(10)) | ||
{ | ||
await collection.InsertOneAsync(eachPerson); | ||
} | ||
|
||
Console.WriteLine("Inserted people... Now finding them..."); | ||
|
||
IAsyncCursor<Person> people = await collection.FindAsync("{}"); | ||
await people.ForEachAsync((person) => Console.WriteLine($"{person.Name} is {person.Age}")); | ||
|
||
await container.DisposeAsync(); | ||
} | ||
} | ||
|
||
|
||
|
||
// Note, if you don't want any generated BSON serializers, you can specify your own generic one like the one below. | ||
// Be aware that you'll need specify static abstracts generation in global config for this to work: | ||
// [assembly: VogenDefaults( | ||
// staticAbstractsGeneration: StaticAbstractsGeneration.MostCommon | StaticAbstractsGeneration.InstanceMethodsAndProperties, | ||
// conversions: Conversions.Default | Conversions.Bson)] | ||
|
||
// ReSharper disable once UnusedType.Global | ||
public class BsonVogenSerializer<TValue, TUnderlyingTypeValue> | ||
: SerializerBase<TValue> where TValue : IVogen<TValue, TUnderlyingTypeValue> | ||
{ | ||
private readonly IBsonSerializer<TUnderlyingTypeValue> _serializer = BsonSerializer.LookupSerializer<TUnderlyingTypeValue>(); | ||
|
||
public override TValue Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) => | ||
TValue.From(_serializer.Deserialize(context, args)); | ||
|
||
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, TValue value) => | ||
_serializer.Serialize(context, args, value.Value); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 5 additions & 0 deletions
5
samples/WebApplication/WebApplication.net8.0.v3.ncrunchproject
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<ProjectConfiguration> | ||
<Settings> | ||
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> | ||
</Settings> | ||
</ProjectConfiguration> |
5 changes: 5 additions & 0 deletions
5
samples/WebApplication/WebApplication.net9.0.v3.ncrunchproject
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<ProjectConfiguration> | ||
<Settings> | ||
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> | ||
</Settings> | ||
</ProjectConfiguration> |
5 changes: 5 additions & 0 deletions
5
samples/WebApplicationConsumer/WebApplicationConsumer.v3.ncrunchproject
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<ProjectConfiguration> | ||
<Settings> | ||
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> | ||
</Settings> | ||
</ProjectConfiguration> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.