Skip to content

Commit

Permalink
Merge pull request #573 from SteveDunn/548-support-servicestack-dot-text
Browse files Browse the repository at this point in the history
Implement #548 ServiceStack.Text
  • Loading branch information
SteveDunn authored Apr 24, 2024
2 parents a691840 + 7217e95 commit c8d8a2e
Show file tree
Hide file tree
Showing 33,717 changed files with 295,439 additions and 231,286 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
8 changes: 7 additions & 1 deletion docs/site/Writerside/topics/reference/Integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,22 @@ public enum Conversions
/// Creates a LinqToDb ValueConverter for converting to and from the type
/// </summary>
LinqToDbValueConverter = 1 << 6,

/// <summary>
/// Sets the SerializeFn and DeSerializeFn members in JsConfig in a static constructor.
/// </summary>
ServiceStackDotText = 1 << 7
}
```

The default, as specified above in the `Defaults` property, is `TypeConverter` and `SystemTextJson`.

[//]: # (TODO: merge this in)

There are other converters/serializer for:
Other converters/serializers are:

* Newtonsoft.Json (NSJ)
* ServiceStack.Text
* Dapper
* EFCore
* [LINQ to DB](https://github.com/linq2db/linq2db)
Expand Down
4 changes: 2 additions & 2 deletions docs/site/Writerside/topics/tutorials/Using-with-JSON.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
In this tutorial, we'll see how to serialize and deserialize value objects.

Vogen can automatically generate the code required for this.
It supports both System.Text.Json (STJ), and Newtonsoft.Json (NSJ)
It supports System.Text.Json (STJ), Newtonsoft.Json (NSJ), and ServiceStack.Text

First, let's see what we get with no conversion generated.
In a C# project that references Vogen, create the following type:
Expand Down Expand Up @@ -34,7 +34,7 @@ You'll see:
Note that the serializer has written the temperature as a composite object (`Value:30`).

This isn't ideal as you probably want the primitive value written.
And also, Vogen won't be able to serialize that composite value back into a value object.
And, Vogen won't be able to serialize that composite value back into a value object.

To get just the primitive value written, change `Celcius` to this and rerun.

Expand Down
1 change: 1 addition & 0 deletions samples/Vogen.Examples/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace Vogen.Examples
{
class Program
{
// ReSharper disable once UnusedParameter.Local
static Task Main(string[] args)
{
var scenarioTypes = typeof(Program).Assembly.GetTypes().Where(t => typeof(IScenario).IsAssignableFrom(t) && t != typeof(IScenario)).ToList();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Vogen.Examples.SerializationAndConversion.EFCore;
using Vogen.Examples.Types;

namespace Vogen.Examples.SerializationAndConversion.EFCore
{
[UsedImplicitly]
public class EfCoreExamples : IScenario
{
public Task Run()
Expand All @@ -16,14 +18,14 @@ public Task Run()
return Task.CompletedTask;
}

private void EfCoreValueConverterUsesValueConverter()
private static void EfCoreValueConverterUsesValueConverter()
{
addAndSave(10);
addAndSave(10);
AddAndSave(10);
AddAndSave(10);

printItems();
PrintItems();

static void addAndSave(int amount)
static void AddAndSave(int amount)
{
using var context = new SomeDbContext();

Expand All @@ -41,7 +43,7 @@ static void addAndSave(int amount)
context.SaveChanges();
}

static void printItems()
static void PrintItems()
{
using var ctx = new SomeDbContext();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ internal class SomeDbContext : DbContext
// var maxSavedId = SomeEntities.Any() ? SomeEntities.Max(e => e.Id.Value) : 0;
// return Math.Max(maxLocalId, maxSavedId) + 1;
// }

protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<SomeEntity>(b =>
Expand All @@ -29,7 +29,7 @@ protected override void OnModelCreating(ModelBuilder builder)
b.Property(e => e.Name).HasConversion(new Name.EfCoreValueConverter());
});
}

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseInMemoryDatabase("SomeDB");
Expand Down Expand Up @@ -66,16 +66,16 @@ internal class SomeIdValueGenerator : ValueGenerator<SomeId>
public override SomeId Next(EntityEntry entry)
{
var entities = ((SomeDbContext)entry.Context).SomeEntities;
var next = Math.Max(maxFrom(entities.Local), maxFrom(entities)) + 1;

var next = Math.Max(MaxFrom(entities.Local), MaxFrom(entities)) + 1;

return SomeId.From(next);

static int maxFrom(IEnumerable<SomeEntity> es)
static int MaxFrom(IEnumerable<SomeEntity> es)
{
return es.Any() ? es.Max(e => e.Id.Value) : 0;
}
}

public override bool GeneratesTemporaryValues => false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public Task Run()
return Task.CompletedTask;
}

private void LinqToDbValueConverterUsesValueConverter()
private static void LinqToDbValueConverterUsesValueConverter()
{
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// ReSharper disable UnusedVariable
#pragma warning disable CS0219
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using ServiceStack.Text;
using Vogen.Examples.Types;
using NewtonsoftJsonSerializer = Newtonsoft.Json.JsonConvert;
using SystemTextJsonSerializer = System.Text.Json.JsonSerializer;
Expand All @@ -16,10 +18,22 @@ public Task Run()
{
SerializeWithNewtonsoftJson();
SerializeWithSystemTextJson();
SerializeWithServiceStackTextJson();

return Task.CompletedTask;
}

public void SerializeWithServiceStackTextJson()
{
SsdtDateTimeOffsetVo orig = SsdtDateTimeOffsetVo.From(_date1);

string json = JsonSerializer.SerializeToString(orig);

var deserialised = JsonSerializer.DeserializeFromString<SsdtDateTimeOffsetVo>(json);

Debug.Assert(deserialised.Value == orig.Value);
}

public void SerializeWithNewtonsoftJson()
{
var g1 = NewtonsoftJsonDateTimeOffsetVo.From(_date1);
Expand Down
4 changes: 0 additions & 4 deletions samples/Vogen.Examples/SyntaxExamples/Types.cs

This file was deleted.

3 changes: 3 additions & 0 deletions samples/Vogen.Examples/Types/DateTimeOffsetVo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ public partial struct NoJsonDateTimeOffsetVo { }
[ValueObject(conversions: Conversions.NewtonsoftJson, underlyingType: typeof(DateTimeOffset))]
public partial struct NewtonsoftJsonDateTimeOffsetVo { }

[ValueObject(conversions: Conversions.ServiceStackDotText, underlyingType: typeof(DateTimeOffset))]
public partial struct SsdtDateTimeOffsetVo { }

[ValueObject(conversions: Conversions.SystemTextJson, underlyingType: typeof(DateTimeOffset))]
public partial struct SystemTextJsonDateTimeOffsetVo { }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,11 @@ public Task Run()
*/
string[] names = new[] { " Fred Flintstone", "Wilma Flintstone\t", " Barney Rubble \t", " \t \t" };

var processor = new Processor();

foreach (string name in names)
{
try
{
processor.Process(ScrapedString.From(name));
Processor.Process(ScrapedString.From(name));
}
catch (ValueObjectValidationException e)
{
Expand All @@ -47,9 +45,9 @@ public Task Run()
return Task.CompletedTask;
}

private class Processor
private static class Processor
{
internal void Process(ScrapedString item) => Console.WriteLine($"Processing \"{item}\"");
internal static void Process(ScrapedString item) => Console.WriteLine($"Processing \"{item}\"");
}
}
}
4 changes: 2 additions & 2 deletions samples/Vogen.Examples/TypicalScenarios/UsingInterfaces.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public Task Run()
return Task.CompletedTask;
}

void ProcessIds(params IHaveAnId<int>[] ids)
static void ProcessIds(params IHaveAnId<int>[] ids)
{
Console.WriteLine("IDs are " + string.Join(", ", ids.Select(i => i.Value)));
}
Expand All @@ -38,7 +38,7 @@ internal partial struct AccountId : IHaveAnId<int>
{
}

// You could derive from this, but if you the type you're wrapping is a reference type,
// You could derive from this, but if the type you're wrapping is a reference type,
// then be aware that there could be severe overhead of wrapping a reference type
// as a value type. One of the goals of Vogen is to not add too much overhead
// (in terms of memory/speed) over using the primitive type itself.
Expand Down
12 changes: 6 additions & 6 deletions samples/Vogen.Examples/TypicalScenarios/ValidationExample.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;

namespace Vogen.Examples.TypicalScenarios.ValidationExamples
{
Expand All @@ -14,19 +15,18 @@ private static Validation Validate(string value) =>
: Validation.Invalid($"must be a dave or david - {value} is neither.");
}

[UsedImplicitly]
internal class ValidationExample : IScenario
{
public Task Run()
{
string[] names = new[] { "Dave Grohl", "David Beckham", "Fred Flintstone" };

var processor = new DaveProcessor();
string[] names = ["Dave Grohl", "David Beckham", "Fred Flintstone"];

foreach (string name in names)
{
try
{
processor.Process(Dave.From(name));
DaveProcessor.Process(Dave.From(name));
}
catch (ValueObjectValidationException e)
{
Expand All @@ -37,9 +37,9 @@ public Task Run()
return Task.CompletedTask;
}

private class DaveProcessor
private static class DaveProcessor
{
internal void Process(Dave dave) => Console.WriteLine($"Processing {dave}");
internal static void Process(Dave dave) => Console.WriteLine($"Processing {dave}");
}
}
}
2 changes: 2 additions & 0 deletions samples/Vogen.Examples/Vogen.Examples.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="JetBrains.Annotations" Version="2023.3.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.0-rc.1.22426.7" />
<PackageReference Include="System.Text.Json" Version="7.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Dapper" Version="2.0.123" />
<PackageReference Include="linq2db" Version="3.7.0" />
<PackageReference Include="ServiceStack.Text" Version="8.2.2" />
</ItemGroup>

<ItemGroup Condition=" '$(UseLocallyBuiltPackage)' != ''">
Expand Down
7 changes: 4 additions & 3 deletions samples/WebApplication/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,13 @@

app.Run();

record WeatherForecast(DateOnly Date, Centigrade TemperatureC, Farenheit temperatureF, string? Summary, City City)
record WeatherForecast(DateOnly Date, Centigrade TemperatureC, Farenheit TemperatureF, string? Summary, City City)
{
}

[ValueObject<string>(parsableForStrings: ParsableForStrings.GenerateMethods)]
public partial class City
[ValueObject<string>]
//[ValueObject<string>(parsableForStrings: ParsableForStrings.GenerateMethods)]
public partial struct City
{
}

Expand Down
9 changes: 6 additions & 3 deletions samples/WebApplicationConsumer/Program.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// See https://aka.ms/new-console-template for more information
using RefitExample;
using ServiceStackDotTextExample;
using Vogen;

using RefitExample;
[assembly: VogenDefaults(conversions:Conversions.ServiceStackDotText | Conversions.SystemTextJson)]

await new RefitRunner().Run();
await ServiceStackTextRunner.Run();
await RefitRunner.Run();


25 changes: 3 additions & 22 deletions samples/WebApplicationConsumer/RefitExample/RefitRunner.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using Refit;
using Vogen;
using WebApplicationConsumer;

namespace RefitExample;

public class RefitRunner
public static class RefitRunner
{
public async Task Run()
public static async Task Run()
{
Console.WriteLine("Refit example");
Console.WriteLine("=============");
Expand Down Expand Up @@ -49,22 +49,3 @@ public interface IJsonPlaceholderApi
[Get("/weatherforecast/{city}")]
Task<List<WeatherForecast>> GetWeatherForecastByCity(City city);
}

public record WeatherForecast(DateOnly Date, Centigrade TemperatureC, Farenheit TemperatureF, string? Summary, City City)
{
}

[ValueObject<string>]
public partial class City
{
}

[ValueObject]
public partial struct Farenheit
{
}

[ValueObject]
public partial struct Centigrade
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using ServiceStack;
using WebApplicationConsumer;

namespace ServiceStackDotTextExample;

public static class ServiceStackTextRunner
{
public static async Task Run()
{
Console.WriteLine("ServiceStack.Text example");
Console.WriteLine("=============");

string json = await "https://localhost:7033/weatherforecast/London"
.GetJsonFromUrlAsync(req => req.With(x => x.UserAgent = "sample.app"));

WeatherForecast[]? forecasts = json.FromJson<WeatherForecast[]>();

foreach (var f in forecasts)
{
Console.WriteLine($"City: {f.City}, TempC: {f.TemperatureC} ({f.TemperatureF.Value}F) - {f.Summary}");
}
}
}

Loading

0 comments on commit c8d8a2e

Please sign in to comment.