Skip to content

Commit

Permalink
Merge branch 'releases/6.x.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
PawelGerr committed Nov 7, 2023
2 parents 724838f + f61bb31 commit fa7ce89
Show file tree
Hide file tree
Showing 125 changed files with 9,836 additions and 7,069 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Thinktecture.SmartEnums;
Expand Down Expand Up @@ -77,6 +77,17 @@ public IActionResult RoundTrip(ProductName name)
return Json(name);
}

[HttpPost("boundary")]
public IActionResult RoundTrip([FromBody] BoundaryWithJsonConverter boundary)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);

_logger.LogInformation("Round trip test with {Type}: {Boundary}", boundary.GetType().Name, boundary);

return Json(boundary);
}

private IActionResult RoundTripValidatableEnum<T, TKey>(T value)
where T : IValidatableEnum, IEnum<TKey>
where TKey : notnull
Expand Down
15 changes: 2 additions & 13 deletions samples/Newtonsoft.Json.AspNetCore.Samples/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,6 @@ public static async Task Main()
var loggerFactory = CreateLoggerFactory();
var server = StartServerAsync(loggerFactory);

// calls
// http://localhost:5000/api/category/fruits
// http://localhost:5000/api/categoryWithConverter/fruits
// http://localhost:5000/api/group/1
// http://localhost:5000/api/group/42
// http://localhost:5000/api/groupWithConverter/1
// http://localhost:5000/api/groupWithConverter/42
// http://localhost:5000/api/productType/groceries
// http://localhost:5000/api/productType/invalid
// http://localhost:5000/api/productTypeWithJsonConverter/groceries
// http://localhost:5000/api/productTypeWithJsonConverter/invalid
// http://localhost:5000/api/productName/bread
// http://localhost:5000/api/productName/a
await DoHttpRequestsAsync(loggerFactory.CreateLogger<Program>());

await server;
Expand All @@ -59,6 +46,8 @@ private static async Task DoHttpRequestsAsync(ILogger logger)
await DoRequestAsync(logger, client, "productTypeWithJsonConverter/invalid"); // invalid
await DoRequestAsync(logger, client, "productName/bread");
await DoRequestAsync(logger, client, "productName/a"); // invalid
await DoRequestAsync(logger, client, "boundary", BoundaryWithJsonConverter.Create(1, 2));
await DoRequestAsync(logger, client, "boundary", jsonBody: "{ \"lower\": 2, \"upper\": 1 }");
}

private static async Task DoRequestAsync(ILogger logger, HttpClient client, string url, object? body = null, string? jsonBody = null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ public IActionResult RoundTripWithQueryString(ProductType productType)
return RoundTrip<ProductType, string>(productType);
}

[HttpGet("boundaryWithFactories/{boundary}")]
public IActionResult RoundTrip(BoundaryWithFactories boundary)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);

_logger.LogInformation("Round trip test with {Type}: {Boundary}", boundary.GetType().Name, boundary);

return Json(boundary);
}

[HttpPost("productType")]
public IActionResult RoundTripPost([FromBody] ProductType productType)
{
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,6 @@ public static async Task Main()

await app;

// calls
// http://localhost:5000/api/category/fruits
// http://localhost:5000/api/categoryWithConverter/fruits
// http://localhost:5000/api/group/1
// http://localhost:5000/api/group/42
// http://localhost:5000/api/groupWithConverter/1
// http://localhost:5000/api/groupWithConverter/42
// http://localhost:5000/api/productType/groceries
// http://localhost:5000/api/productType/invalid
// http://localhost:5000/api/productTypeWithJsonConverter/groceries
// http://localhost:5000/api/productTypeWithJsonConverter/invalid
// http://localhost:5000/api/productName/bread
// http://localhost:5000/api/productName/a
// http://localhost:5000/api/boundary
await DoHttpRequestsAsync(loggerFactory.CreateLogger<Program>(), startMinimalWebApi);

await Task.Delay(5000);
Expand All @@ -69,6 +55,8 @@ private static async Task DoHttpRequestsAsync(ILogger logger, bool forMinimalWeb
await DoRequestAsync(logger, client, "productType?productType=groceries");
await DoRequestAsync(logger, client, "productType", "groceries");
await DoRequestAsync(logger, client, "productType/invalid"); // invalid
await DoRequestAsync(logger, client, "boundaryWithFactories/1:2"); // uses custom factory "[ValueObjectFactory<string>]"
await DoRequestAsync(logger, client, "boundaryWithFactories/invalid"); // invalid

if (forMinimalWebApi)
await DoRequestAsync(logger, client, "productTypeWithFilter?productType=invalid"); // invalid
Expand Down Expand Up @@ -143,7 +131,6 @@ private static Task StartServerAsync(ILoggerFactory loggerFactory)
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.Converters.Add(new ValueObjectJsonConverterFactory());
options.JsonSerializerOptions.Converters.Add(new DateOnlyConverter());
});
})
.Build();
Expand All @@ -159,7 +146,6 @@ private static Task StartMinimalWebApiAsync(ILoggerFactory loggerFactory)
.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.Converters.Add(new ValueObjectJsonConverterFactory());
options.SerializerOptions.Converters.Add(new DateOnlyConverter());
});

var app = builder.Build();
Expand All @@ -182,6 +168,7 @@ private static Task StartMinimalWebApiAsync(ILoggerFactory loggerFactory)
return next(context);
});
routeGroup.MapGet("boundaryWithFactories/{boundary}", (BoundaryWithFactories boundary) => boundary);
routeGroup.MapPost("productType", ([FromBody] ProductType productType) => productType);
routeGroup.MapPost("productTypeWrapper", ([FromBody] ProductTypeWrapper productType) => productType);
routeGroup.MapGet("productTypeWithJsonConverter/{productType}", (ProductTypeWithJsonConverter productType) => productType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace Thinktecture.Validation;

public class BoundValueObject<T, TKey> : IBoundParam
where T : IKeyedValueObject<T, TKey>
where T : IValueObjectFactory<T, TKey>
where TKey : IParsable<TKey>
{
private readonly T? _item;
Expand All @@ -30,7 +30,7 @@ public static bool TryParse(string s, IFormatProvider? formatProvider, out Bound
}
else
{
var validationResult = T.Validate(key, out var item);
var validationResult = T.Validate(key, formatProvider, out var item);

if (validationResult is null || item is IValidatableEnum)
{
Expand All @@ -47,7 +47,7 @@ public static bool TryParse(string s, IFormatProvider? formatProvider, out Bound
}

public class BoundValueObject<T> : IBoundParam
where T : IKeyedValueObject<T, string>
where T : IValueObjectFactory<T, string>
{
private readonly T? _item;
public T? Value => Error is null ? _item : throw new ValidationException(Error);
Expand All @@ -66,7 +66,7 @@ private BoundValueObject(string error)

public static bool TryParse(string s, IFormatProvider? formatProvider, out BoundValueObject<T> value)
{
var validationResult = T.Validate(s, out var item);
var validationResult = T.Validate(s, formatProvider, out var item);

if (validationResult is null || item is IValidatableEnum)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public BenchmarkContext()
var services = new ServiceCollection()
.AddLogging(builder => builder.AddConsole())
.AddDbContext<BenchmarkDbContext>(builder => builder
.UseSqlServer("Server=localhost;Database=TT_RE_Benchmarking;Integrated Security=true;")
.UseSqlServer("Server=localhost;Database=TT_RE_Benchmarking;Integrated Security=true;TrustServerCertificate=true;")
.UseLoggerFactory(NullLoggerFactory.Instance)
.UseValueObjectValueConverter());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

namespace Thinktecture.Benchmarks;

[MemoryDiagnoser]
public class ItemSearch
{
public class SmartEnum
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
namespace Thinktecture.Benchmarks;

// ReSharper disable InconsistentNaming
[MemoryDiagnoser]
public class LoadingSmartEnums
{
private BenchmarkContext? _benchmarkContext;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
namespace Thinktecture.Benchmarks;

// ReSharper disable InconsistentNaming
[MemoryDiagnoser]
public class LoadingValueObjects
{
private BenchmarkContext? _benchmarkContext;
Expand All @@ -19,6 +18,7 @@ public class LoadingValueObjects

private readonly Entity_with_ValueObjects[] _Entity_with_ValueObjects = Enumerable.Range(1, _NUMBER_OF_ENTITIES).Select(i => new Entity_with_ValueObjects(i)).ToArray();
private readonly Entity_without_ValueObjects[] _Entity_without_ValueObjects = Enumerable.Range(1, _NUMBER_OF_ENTITIES).Select(i => new Entity_without_ValueObjects(i)).ToArray();
private readonly Entity_with_StructValueObjects[] _Entity_with_StructValueObjects = Enumerable.Range(1, _NUMBER_OF_ENTITIES).Select(i => new Entity_with_StructValueObjects(i)).ToArray();

[GlobalSetup]
public void Initialize()
Expand All @@ -36,6 +36,9 @@ public void Initialize()
_dbContext.RemoveRange(_dbContext.Entity_without_ValueObjects);
_dbContext.Entity_without_ValueObjects.AddRange(_Entity_without_ValueObjects);

_dbContext.RemoveRange(_dbContext.Entity_with_StructValueObjects);
_dbContext.Entity_with_StructValueObjects.AddRange(_Entity_with_StructValueObjects);

_dbContext.SaveChanges();
}

Expand Down Expand Up @@ -63,4 +66,10 @@ public async Task Entity_without_ValueObjects()
{
await _dbContext!.Entity_without_ValueObjects.ToListAsync();
}

[Benchmark]
public async Task Entity_with_StructValueObjects()
{
await _dbContext!.Entity_with_StructValueObjects.ToListAsync();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

namespace Thinktecture.Benchmarks;

[MemoryDiagnoser]
public class SingleItemCollectionBenchmarks
{
private readonly IReadOnlyList<int> _singleItemCollection = SingleItem.Collection(42);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

namespace Thinktecture.Benchmarks;

[MemoryDiagnoser]
public class SingleItemSetBenchmarks
{
private readonly IReadOnlySet<int> _singleItemSet = SingleItem.Set(42);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public class BenchmarkDbContext : DbContext

public DbSet<Entity_with_ValueObjects> Entity_with_ValueObjects { get; set; } = null!;
public DbSet<Entity_without_ValueObjects> Entity_without_ValueObjects { get; set; } = null!;
public DbSet<Entity_with_StructValueObjects> Entity_with_StructValueObjects { get; set; } = null!;

public BenchmarkDbContext(DbContextOptions<BenchmarkDbContext> options)
: base(options)
Expand Down Expand Up @@ -66,5 +67,12 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
builder.Property(e => e.Name).HasMaxLength(100);
builder.Property(e => e.Description).HasMaxLength(200);
});

modelBuilder.Entity<Entity_with_StructValueObjects>(builder =>
{
builder.Property(e => e.Id).ValueGeneratedNever();
builder.Property(e => e.Name).HasMaxLength(100);
builder.Property(e => e.Description).HasMaxLength(200);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ static partial void ValidateFactoryArguments(ref ValidationResult? validationRes
{
if (String.IsNullOrWhiteSpace(value))
{
value = null!;
validationResult = new ValidationResult("Description cannot be empty.");
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.ComponentModel.DataAnnotations;

namespace Thinktecture.Database;

[ValueObject]
public readonly partial struct DescriptionStruct
{
private readonly string _value;

static partial void ValidateFactoryArguments(ref ValidationResult? validationResult, ref string value)
{
if (String.IsNullOrWhiteSpace(value))
{
value = null!;
validationResult = new ValidationResult("Description cannot be empty.");
return;
}

value = value.Trim();

if (value.Length < 2)
validationResult = new ValidationResult("Description cannot be less than 2 characters.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace Thinktecture.Database;

// ReSharper disable InconsistentNaming
public class Entity_with_StructValueObjects
{
public int Id { get; set; }
public NameStruct Name { get; set; }
public DescriptionStruct Description { get; set; }

// ReSharper disable once UnusedMember.Local
private Entity_with_StructValueObjects(int id, NameStruct name, DescriptionStruct description)
{
Id = id;
Name = name;
Description = description;
}

public Entity_with_StructValueObjects(int index)
{
Id = index;
Name = NameStruct.Create($"Name {index}");
Description = DescriptionStruct.Create($"Description {index}");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ static partial void ValidateFactoryArguments(ref ValidationResult? validationRes
{
if (String.IsNullOrWhiteSpace(value))
{
value = null!;
validationResult = new ValidationResult("Name cannot be empty.");
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.ComponentModel.DataAnnotations;

namespace Thinktecture.Database;

[ValueObject]
public readonly partial struct NameStruct
{
private readonly string _value;

static partial void ValidateFactoryArguments(ref ValidationResult? validationResult, ref string value)
{
if (String.IsNullOrWhiteSpace(value))
{
value = null!;
validationResult = new ValidationResult("Name cannot be empty.");
return;
}

value = value.Trim();

if (value.Length < 2)
validationResult = new ValidationResult("Name cannot be less than 2 characters.");
}
}
Loading

0 comments on commit fa7ce89

Please sign in to comment.