Skip to content

Commit

Permalink
Adding ArgumentNullExceptionExtensions, JsonAnyTypeConverter, and Obj…
Browse files Browse the repository at this point in the history
…ectQueryStringExtensions,
  • Loading branch information
dgmjr committed Jun 6, 2024
1 parent 2f93907 commit 2174731
Show file tree
Hide file tree
Showing 13 changed files with 246 additions and 32 deletions.
8 changes: 5 additions & 3 deletions Redis/EndPointCollectionJsonConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ namespace Dgmjr.Redis.Extensions;

public class EndPointCollectionJsonConverter : JsonConverter<EndPointCollection>
{
const int StandardPort = 6379;
private const int StandardPort = 6379;

const string Localhost = "localhost";
private const string Localhost = "localhost";

public override bool CanConvert(type typeToConvert)
{
Expand Down Expand Up @@ -68,7 +68,9 @@ Jso options
}
else
{
endpoint = endpoint is DnsEndPoint dnsEndPoint ? new DnsEndPoint(dnsEndPoint.Host, port) : (EndPoint)new DnsEndPoint(Localhost, port);
endpoint = endpoint is DnsEndPoint dnsEndPoint
? new DnsEndPoint(dnsEndPoint.Host, port)
: (EndPoint)new DnsEndPoint(Localhost, port);
}
break;
case nameof(IPEndPoint.Address):
Expand Down
35 changes: 14 additions & 21 deletions Redis/RedisAutoConfigurator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,30 @@ namespace Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Hosting;

public class RedisAutoConfigurator : IHostingStartup, IStartupFilter
public class RedisAutoConfigurator : ConfiguratorBase<RedisAutoConfigurator>
{
private const string Redis = nameof(Redis);
private const string ResponseCaching = nameof(ResponseCaching);
public ConfigurationOrder Order => ConfigurationOrder.AnyTime;

public void Configure(IWebHostBuilder builder)
protected override void ConfigureServices(IServiceCollection services)
{
builder.ConfigureServices((context, services) =>
var redisOptions = Configuration.GetSection(Redis).Get<RedisCacheOptions>();
if (redisOptions?.UseRedis == true)
{
var redisOptions = context.Configuration.GetSection(Redis).Get<RedisCacheOptions>();
if (redisOptions?.UseRedis == true)
{
services.AddRedisCaching(context.Configuration);
}
});
services.AddRedisCaching(Configuration);
}
}

public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
protected override void Configure(IApplicationBuilder app)
{
return builder =>
var redisOptions = app.ApplicationServices
.GetRequiredService<IConfiguration>()
.GetSection(Redis)
.Get<RedisCacheOptions>();
if (redisOptions?.UseRedis == true)
{
var redisOptions = builder.ApplicationServices
.GetRequiredService<IConfiguration>()
.GetSection(Redis)
.Get<RedisCacheOptions>();
if (redisOptions?.UseRedis == true)
{
builder.UseRedisCaching();
}
next(builder);
};
app.UseRedisCaching();
}
}
}
2 changes: 1 addition & 1 deletion System/Dgmjr.System.Extensions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;net6.0;net8.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;netstandard2.1;net6.0;net8.0;net9.0</TargetFrameworks>
<!-- <TargetFrameworks>netstandard1.7;netstandard1.6;netstandard1.5;netstandard1.3</TargetFrameworks> -->
<!-- <TargetFrameworks>netstandard1.7;netstandard1.6;netstandard1.5;netstandard1.3</TargetFrameworks> -->
<!-- <TargetFramework>net7.0</TargetFramework> -->
Expand Down
2 changes: 2 additions & 0 deletions System/Dgmjr.System.Extensions.props
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
<Using Include="System.Xml.Linq.XName" Alias="XN"/>
<Using Include="System.Xml.Linq.XNamespace" Alias="XNS"/>
<Using Include="System.Xml.Linq.XNode" Alias="XO"/>
<Using Include="System.Collections.Generic.Dictionary%3cstring,object%3e" Alias="StringObjectDictionary" />
<Using Include="System.Collections.Generic.IDictionary%3cstring,object%3e" Alias="IStringObjectDictionary" />
<Using Include="System.Collections.Generic.CaseInsensitiveKeyDictionary%3cstring%3e" Alias="CaseInsensitiveStringDictionary" />
<Using Include="System.Collections.Generic.CaseInsensitiveKeyDictionary%3cstring%3e" Alias="CaseInsensitiveStringKeyDictionary" />
<Using Include="System.Int128" Alias="vlong /* very long */" Condition="$(DefineConstants.Contains('NET7_0_OR_GREATER'))" />
Expand Down
60 changes: 60 additions & 0 deletions System/System.Net.Http/ObjectQueryStringExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* ObjectQueryStringExtensions.cs
* Created: 2024-04-27T19:45:11-04:00
* Modified: 2024-04-27T19:45:13-04:00
* Author: David G. Moore, Jr. <[email protected]>
* Copyright: © 2022 - 2024 David G. Moore, Jr., All Rights Reserved
* License: MIT (https://opensource.org/licenses/MIT)
*/

namespace System.Net.Http;

public static class ObjectQueryStringExtensions
{
// public static string ToQueryString<T>(this T t)
// {
// return (t as object).ToQueryString(typeof(T).GetRuntimeProperties().ToArray());
// }

public static string ToQueryString(this object o)
{
var properties = o.GetType().GetRuntimeProperties().ToArray();
var sb = new StringBuilder();
foreach (var property in properties)
{
var value = property.GetValue(o);

// if (property.GetCustomAttributes<JConverterAttribute>().Any())
// {
// var converter = property.GetCustomAttribute<JConverterAttribute>().ConverterType;
// var instance = Activator.CreateInstance(converter) as JConverter;
// var method = converter.GetMethod("Write");
// method.Invoke(instance, new object[] { sb, value, null });

// }

if (value is null)
{
continue;
}
else if (value is Enum e)
{
value = e.GetEnumMemberValue() ?? e.GetName() ?? e.ToString();
}

if (sb.Length > 0)
{
sb.Append('&');
}

var propName = (
property.GetCustomAttribute<JPropAttribute>()?.Name
?? property.Name.FromCasing('\0', false)
);

sb.Append($"{propName}={value}");
}

return sb.ToString();
}
}
41 changes: 41 additions & 0 deletions System/System.Text.Json/EnumMemberValueToStringConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* EnumValueToStringConverter.cs
* Created: 2024-05-05T20:43:59-04:00
* Modified: 2024-05-05T20:43:59-04:00
* Author: David G. Moore, Jr. <[email protected]>
* Copyright: © 2022 - 2024 David G. Moore, Jr., All Rights Reserved
* License: MIT (https://opensource.org/licenses/MIT)
*/

using System.Text.Json;

namespace System.Text.Json;

public class EnumMemberValueToStringConverter<TEnum> : JsonConverter<TEnum>
where TEnum : struct, Enum
{
public override TEnum Read(ref Utf8JsonReader reader, type typeToConvert, Jso options)
{
if (reader.TokenType != JTokenType.String)
{
throw new JException($"Expected a string but got {reader.TokenType}");
}

var enumString = reader.GetString() ?? throw new JException("Expected a non-null string");

foreach (var value in Enums.GetValues<TEnum>())
{
if (value.GetEnumMemberValue() == enumString)
{
return value;
}
}

throw new JException($"Unable to convert '{enumString}' to {typeof(TEnum).Name}");
}

public override void Write(Utf8JsonWriter writer, TEnum value, Jso options)
{
writer.WriteStringValue(value.GetEnumMemberValue());
}
}
12 changes: 12 additions & 0 deletions System/System.Text.Json/JsonAnyTypeConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* JsonAnyTypeConverter.cs
* Created: 2024-06-05T13:48:06-04:00
* Modified: 2024-06-05T13:48:06-04:00
* Author: David G. Moore, Jr. <[email protected]>
* Copyright: © 2022 - 2024 David G. Moore, Jr., All Rights Reserved
* License: MIT (https://opensource.org/licenses/MIT)
*/

namespace System.Text.Json;

public class JsonAnyTypeConverter : JsonAnyTypeConverter<object> { }
57 changes: 57 additions & 0 deletions System/System.Text.Json/JsonAnyTypeConverter{T}.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* JsonAnyTypeSerilalizer.cs
* Created: 2024-06-05T13:21:08-04:00
* Modified: 2024-06-05T13:21:08-04:00
* Author: David G. Moore, Jr. <[email protected]>
* Copyright: © 2022 - 2024 David G. Moore, Jr., All Rights Reserved
* License: MIT (https://opensource.org/licenses/MIT)
*/

namespace System.Text.Json;

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

public class JsonAnyTypeConverter<T> : JsonConverter<T>
where T : new()
{
public const string DefaultDiscriminator = "$type";

protected virtual object Construct(type t) => Activator.CreateInstance(t);

public override T? Read(ref Utf8JsonReader reader, type typeToConvert, Jso options)
{
var jObject = JDoc.ParseValue(ref reader).RootElement;
var typeName = jObject.GetProperty("$type").GetString();
var value = (T)Construct(typeToConvert);

foreach (var property in jObject.EnumerateObject())
{
if (property.Name == DefaultDiscriminator)
{
continue;
}

var propertyType = type.GetType(typeName);
var propertyValue = Deserialize(property.Value.ToString(), propertyType, options);
var objectProperty = typeToConvert.GetProperty(property.Name);
objectProperty.SetValue(value, propertyValue);
}
return value;
}

public override void Write(Utf8JsonWriter writer, T value, Jso options)
{
writer.WriteStartObject();
var type = value.GetType();
writer.WriteString(DefaultDiscriminator, type.AssemblyQualifiedName);
foreach (var property in type.GetProperties())
{
var propertyValue = property.GetValue(value);
writer.WritePropertyName(property.Name);
Serialize(writer, propertyValue, property.PropertyType, options);
}
writer.WriteEndObject();
}
}
14 changes: 9 additions & 5 deletions System/System/ArgumentNullExceptionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,33 @@ namespace System;

public static class ArgumentNullExceptionExtensions
{
public static void ThrowIfNull(
this object? value,
public static T ThrowIfNull<T>(
this T? value,
[CallerArgumentExpression("value")] string? paramName = null
)
{
if (value is null)
{
throw new ArgumentNullException(paramName);
}
else
return value;
}
}

public static class ArgumentExceptionExtensions
{
public static void ThrowIfNullOrEmpty(
this object? value,
public static T ThrowIfNullOrEmpty<T>(
this T? value,
[CallerArgumentExpression("value")] string? paramName = null
)
{
if (IsNullOrEmpty(value.ToString()))
if (IsNullOrEmpty(value?.ToString()))
{
throw new ArgumentException(paramName);
}
else
return value;
}
}

Expand Down
31 changes: 31 additions & 0 deletions System/System/EnumExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,35 @@ public static string GetName<T>(this T e)
var attribute = e.GetCustomAttribute<UriAttribute>();
return attribute?.Value;
}

public static System.Runtime.Serialization.EnumMemberAttribute? GetEnumMember<T>(this T e)
where T : Enum
{
var attribute = e.GetCustomAttribute<System.Runtime.Serialization.EnumMemberAttribute>();
return attribute;
}

public static string GetEnumMemberValue<T>(this T e)
where T : Enum
{
var attribute = e.GetEnumMember();
return attribute?.Value ?? e.ToString();
}

public static string[] GetStringValues<T>(this T e)
where T : Enum
{
return new[]
{
e.ToString(),
e.GetName(),
e.GetShortName(),
e.GetDisplayName(),
e.GetUri().ToString(),
e.GetGuid().ToString()
}
.Concat(e.GetSynonyms())
.Distinct()
.ToArray();
}
}
9 changes: 9 additions & 0 deletions System/System/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ public static T[] GetValues<T>()
return Enum.GetValues(typeof(T)).OfType<T>().ToArray();
}

public static T? SlowParse<T>(string s)
where T : Enum
{
return Find(
GetValues<T>(),
e => e.GetStringValues().Contains(s, StringComparer.OrdinalIgnoreCase)
);
}

public static T Parse<T>(string s)
where T : Enum
{
Expand Down
3 changes: 2 additions & 1 deletion System/System/ObjectExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ public static async Task<string> ReadAssemblyResourceAllTextAsync<T>(
string resourceName
) => await Extensions.ReadAssemblyResourceAllTextAsync(typeof(T).Assembly, resourceName);

public static T To<T>(this object value) => (T)Convert.ChangeType(value, typeof(T));
public static T To<T>(this object value) =>
value is T t ? t : (T)Convert.ChangeType(value, typeof(T));

public static object? GetPropertyValue(this object obj, string propertyName)
{
Expand Down
4 changes: 3 additions & 1 deletion Tests/Dgmjr.System.Extensions.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<TargetFrameworks>net9.0</TargetFrameworks>
<TargetFrameworks>net9.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand Down

0 comments on commit 2174731

Please sign in to comment.