Skip to content

Commit

Permalink
Working on XML comments and other errors (#489)
Browse files Browse the repository at this point in the history
Co-authored-by: Steve Smith <[email protected]>
  • Loading branch information
sdepouw and ardalis authored Jan 18, 2024
1 parent 7a2c775 commit a429eb6
Show file tree
Hide file tree
Showing 43 changed files with 1,025 additions and 444 deletions.
7 changes: 7 additions & 0 deletions src/SmartEnum.AutoFixture/SmartEnumCustomization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@ namespace Ardalis.SmartEnum.AutoFixture
{
using global::AutoFixture;

/// <summary>
///
/// </summary>
public class SmartEnumCustomization : ICustomization
{
/// <summary>
///
/// </summary>
/// <param name="fixture"></param>
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new SmartEnumSpecimenBuilder());
Expand Down
9 changes: 9 additions & 0 deletions src/SmartEnum.AutoFixture/SmartEnumSpecimenBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,18 @@ namespace Ardalis.SmartEnum.AutoFixture
using System;
using global::AutoFixture.Kernel;

/// <summary>
///
/// </summary>
public class SmartEnumSpecimenBuilder :
ISpecimenBuilder
{
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="context"></param>
/// <returns></returns>
public object Create(object request, ISpecimenContext context)
{
if (request is Type type && type.TryGetValues(out var enums))
Expand Down
221 changes: 111 additions & 110 deletions src/SmartEnum.EFCore/SmartEnumConverterExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,155 +9,156 @@
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Reflection;
using System.Text;

namespace SmartEnum.EFCore
namespace SmartEnum.EFCore;

/// <summary>
///
/// </summary>
public static class SmartEnumConverterExtensions
{
public static class SmartEnumConverterExtensions
/// <summary>
/// Adds a converter for all properties derived from <see cref="SmartEnum{TValue, TKey}"/>
/// so that entity framework core can work with it.
/// </summary>
public static void ConfigureSmartEnum(this ModelConfigurationBuilder configurationBuilder)
{
var modelBuilder = configurationBuilder.CreateModelBuilder(null);
var propertyTypes = modelBuilder.Model.GetEntityTypes()
.SelectMany(e => e.ClrType.GetProperties())
.Where(p => TypeUtil.IsDerived(p.PropertyType, typeof(SmartEnum<,>)))
.Where(p => p.GetCustomAttribute<NotMappedAttribute>() == null)
.Select(p => p.PropertyType)
.Distinct();

foreach (var propertyType in propertyTypes)
{
var (enumType, keyType) = TypeUtil.GetEnumAndValueTypes(propertyType, typeof(SmartEnum<,>));
if (enumType != propertyType)
{
// Only enum types 'TEnum' which extend SmartEnum<TEnum, TValue> are currently supported.
continue;
}

var converterType = typeof(SmartEnumConverter<,>).MakeGenericType(propertyType, keyType);

configurationBuilder.Properties(propertyType)
.HaveConversion(converterType);
}
}

/// <summary>
/// Adds a converter for all properties derived from <see cref="SmartEnum{TValue, TKey}"/>
/// so that entity framework core can work with it.
/// </summary>
/// <param name="modelBuilder"></param>
public static void ConfigureSmartEnum(this ModelBuilder modelBuilder)
{
/// <summary>
/// Adds a converter for all properties derived from <see cref="SmartEnum{TValue, TKey}"/>
/// so that entity framework core can work with it.
/// </summary>
public static void ConfigureSmartEnum(this ModelConfigurationBuilder configurationBuilder)
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
var modelBuilder = configurationBuilder.CreateModelBuilder(null);
var propertyTypes = modelBuilder.Model.GetEntityTypes()
.SelectMany(e => e.ClrType.GetProperties())
var properties = entityType.ClrType.GetProperties()
.Where(p => TypeUtil.IsDerived(p.PropertyType, typeof(SmartEnum<,>)))
.Where(p => p.GetCustomAttribute<NotMappedAttribute>() == null)
.Select(p => p.PropertyType)
.Distinct();
.Where(p => p.GetCustomAttribute<NotMappedAttribute>() == null);

foreach (var propertyType in propertyTypes)
foreach (var property in properties)
{
var (enumType, keyType) = TypeUtil.GetEnumAndValueTypes(propertyType, typeof(SmartEnum<,>));
if (enumType != propertyType)
var (enumType, keyType) = TypeUtil.GetEnumAndValueTypes(property.PropertyType, typeof(SmartEnum<,>));
if (enumType != property.PropertyType)
{
// Only enum types 'TEnum' which extend SmartEnum<TEnum, TValue> are currently supported.
continue;
}

var converterType = typeof(SmartEnumConverter<,>).MakeGenericType(propertyType, keyType);
var converterType = typeof(SmartEnumConverter<,>).MakeGenericType(property.PropertyType, keyType);

configurationBuilder.Properties(propertyType)
.HaveConversion(converterType);
}
}
var converter = (ValueConverter)Activator.CreateInstance(converterType);

/// <summary>
/// Adds a converter for all properties derived from <see cref="SmartEnum{TValue, TKey}"/>
/// so that entity framework core can work with it.
/// </summary>
/// <param name="modelBuilder"></param>
public static void ConfigureSmartEnum(this ModelBuilder modelBuilder)
{
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
var properties = entityType.ClrType.GetProperties()
.Where(p => TypeUtil.IsDerived(p.PropertyType, typeof(SmartEnum<,>)))
.Where(p => p.GetCustomAttribute<NotMappedAttribute>() == null);

foreach (var property in properties)
var propertyBuilder = GetPropertyBuilder(modelBuilder, entityType, property.Name);
if (propertyBuilder == null)
{
var (enumType, keyType) = TypeUtil.GetEnumAndValueTypes(property.PropertyType, typeof(SmartEnum<,>));
if (enumType != property.PropertyType)
{
// Only enum types 'TEnum' which extend SmartEnum<TEnum, TValue> are currently supported.
continue;
}

var converterType = typeof(SmartEnumConverter<,>).MakeGenericType(property.PropertyType, keyType);
continue;
}

var converter = (ValueConverter)Activator.CreateInstance(converterType);
propertyBuilder.HasConversion(converter);
}
}
}

var propertyBuilder = GetPropertyBuilder(modelBuilder, entityType, property.Name);
if (propertyBuilder == null)
{
continue;
}
private static PropertyBuilder GetPropertyBuilder(
ModelBuilder modelBuilder,
IMutableEntityType entityType,
string propertyName)
{
var ownershipPath = new List<IMutableForeignKey>();

propertyBuilder.HasConversion(converter);
}
var currEntityType = entityType;
while (currEntityType.IsOwned())
{
var ownership = currEntityType.FindOwnership();
if (ownership == null)
{
return null;
}

ownershipPath.Add(ownership);
currEntityType = ownership.PrincipalEntityType;
}

private static PropertyBuilder GetPropertyBuilder(
ModelBuilder modelBuilder,
IMutableEntityType entityType,
string propertyName)
var entityTypeBuilder = modelBuilder.Entity(currEntityType.Name);
if (ownershipPath.Count == 0)
{
var ownershipPath = new List<IMutableForeignKey>();
return entityTypeBuilder.Property(propertyName);
}

var currEntityType = entityType;
while (currEntityType.IsOwned())
{
var ownership = currEntityType.FindOwnership();
if (ownership == null)
{
return null;
}
var ownedNavigationBuilder = GetOwnedNavigationBuilder(entityTypeBuilder, ownershipPath);
if (ownedNavigationBuilder == null)
{
return null;
}

ownershipPath.Add(ownership);
currEntityType = ownership.PrincipalEntityType;
}
return ownedNavigationBuilder.Property(propertyName);
}

var entityTypeBuilder = modelBuilder.Entity(currEntityType.Name);
if (ownershipPath.Count == 0)
{
return entityTypeBuilder.Property(propertyName);
}
private static OwnedNavigationBuilder GetOwnedNavigationBuilder(
EntityTypeBuilder entityTypeBuilder,
List<IMutableForeignKey> ownershipPath)
{
OwnedNavigationBuilder ownedNavigationBuilder = null;
for (int i = ownershipPath.Count - 1; i >= 0; i--)
{
var ownership = ownershipPath[i];

var ownedNavigationBuilder = GetOwnedNavigationBuilder(entityTypeBuilder, ownershipPath);
if (ownedNavigationBuilder == null)
var navigation = ownership.GetNavigation(pointsToPrincipal: false);
if (navigation == null)
{
return null;
}

return ownedNavigationBuilder.Property(propertyName);
}

private static OwnedNavigationBuilder GetOwnedNavigationBuilder(
EntityTypeBuilder entityTypeBuilder,
List<IMutableForeignKey> ownershipPath)
{
OwnedNavigationBuilder ownedNavigationBuilder = null;
for (int i = ownershipPath.Count - 1; i >= 0; i--)
if (ownedNavigationBuilder == null)
{
var ownership = ownershipPath[i];

var navigation = ownership.GetNavigation(pointsToPrincipal: false);
if (navigation == null)
if (ownership.IsUnique)
{
return null;
ownedNavigationBuilder = entityTypeBuilder.OwnsOne(ownership.DeclaringEntityType.Name, navigation.Name);
}

if (ownedNavigationBuilder == null)
else
{
if (ownership.IsUnique)
{
ownedNavigationBuilder = entityTypeBuilder.OwnsOne(ownership.DeclaringEntityType.Name, navigation.Name);
}
else
{
ownedNavigationBuilder = entityTypeBuilder.OwnsMany(ownership.DeclaringEntityType.Name, navigation.Name);
}
ownedNavigationBuilder = entityTypeBuilder.OwnsMany(ownership.DeclaringEntityType.Name, navigation.Name);
}
}
else
{
if (ownership.IsUnique)
{
ownedNavigationBuilder = ownedNavigationBuilder.OwnsOne(ownership.DeclaringEntityType.Name, navigation.Name);
}
else
{
if (ownership.IsUnique)
{
ownedNavigationBuilder = ownedNavigationBuilder.OwnsOne(ownership.DeclaringEntityType.Name, navigation.Name);
}
else
{
ownedNavigationBuilder = ownedNavigationBuilder.OwnsMany(ownership.DeclaringEntityType.Name, navigation.Name);
}
ownedNavigationBuilder = ownedNavigationBuilder.OwnsMany(ownership.DeclaringEntityType.Name, navigation.Name);
}

}

return ownedNavigationBuilder;

}

return ownedNavigationBuilder;
}
}
27 changes: 27 additions & 0 deletions src/SmartEnum.JsonNet/SmartEnumNameConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,35 @@ namespace Ardalis.SmartEnum.JsonNet
using Newtonsoft.Json;
using System;

/// <summary>
///
/// </summary>
/// <typeparam name="TEnum"></typeparam>
/// <typeparam name="TValue"></typeparam>
public class SmartEnumNameConverter<TEnum, TValue> : JsonConverter<TEnum>
where TEnum : SmartEnum<TEnum, TValue>
where TValue : IEquatable<TValue>, IComparable<TValue>
{
/// <summary>
/// Defaults to true.
/// </summary>
public override bool CanRead => true;

/// <summary>
/// Defaults to true.
/// </summary>
public override bool CanWrite => true;

/// <summary>
///
/// </summary>
/// <param name="reader"></param>
/// <param name="objectType"></param>
/// <param name="existingValue"></param>
/// <param name="hasExistingValue"></param>
/// <param name="serializer"></param>
/// <returns></returns>
/// <exception cref="JsonSerializationException"></exception>
public override TEnum ReadJson(JsonReader reader, Type objectType, TEnum existingValue, bool hasExistingValue, JsonSerializer serializer)
{
switch (reader.TokenType)
Expand All @@ -37,6 +58,12 @@ TEnum GetFromName(string name)
}
}

/// <summary>
///
/// </summary>
/// <param name="writer"></param>
/// <param name="value"></param>
/// <param name="serializer"></param>
public override void WriteJson(JsonWriter writer, TEnum value, JsonSerializer serializer)
{
if (value is null)
Expand Down
27 changes: 27 additions & 0 deletions src/SmartEnum.JsonNet/SmartEnumValueConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,34 @@ namespace Ardalis.SmartEnum.JsonNet
using Newtonsoft.Json;
using System;

/// <summary>
///
/// </summary>
/// <typeparam name="TEnum"></typeparam>
/// <typeparam name="TValue"></typeparam>
public class SmartEnumValueConverter<TEnum, TValue> : JsonConverter<TEnum>
where TEnum : SmartEnum<TEnum, TValue>
where TValue : IEquatable<TValue>, IComparable<TValue>
{
/// <summary>
/// Defaults to true.
/// </summary>
public override bool CanRead => true;
/// <summary>
/// Defaults to true.
/// </summary>
public override bool CanWrite => true;

/// <summary>
///
/// </summary>
/// <param name="reader"></param>
/// <param name="objectType"></param>
/// <param name="existingValue"></param>
/// <param name="hasExistingValue"></param>
/// <param name="serializer"></param>
/// <returns></returns>
/// <exception cref="JsonSerializationException"></exception>
public override TEnum ReadJson(JsonReader reader, Type objectType, TEnum existingValue, bool hasExistingValue, JsonSerializer serializer)
{
try
Expand All @@ -32,6 +53,12 @@ public override TEnum ReadJson(JsonReader reader, Type objectType, TEnum existin
}
}

/// <summary>
///
/// </summary>
/// <param name="writer"></param>
/// <param name="value"></param>
/// <param name="serializer"></param>
public override void WriteJson(JsonWriter writer, TEnum value, JsonSerializer serializer)
{
if (value is null)
Expand Down
Loading

0 comments on commit a429eb6

Please sign in to comment.