Last active
May 10, 2022 17:12
-
-
Save bh3605/b17a005b29019f794dff80f1d0a167e4 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Reflection; | |
public class TypeSafeEnum<T> where T : class | |
{ | |
TypeSafeEnum(string name, T typeSafeEnum) | |
{ | |
Name = name; | |
Enum = typeSafeEnum; | |
} | |
public static readonly TypeSafeEnum<T>[] Enums = | |
typeof(T) //Static Properties | |
.GetProperties(BindingFlags.Public | BindingFlags.Static) | |
.Where(x => x.PropertyType == typeof(T)) | |
.Select(x => new TypeSafeEnum<T>(x.Name, (T)x.GetValue(null))) | |
.Union(typeof(T) //Static fields | |
.GetFields(BindingFlags.Public | BindingFlags.Static) | |
.Where(x => x.FieldType == typeof(T)) | |
.Select(x => new TypeSafeEnum<T>(x.Name, (T)x.GetValue(null)))) | |
.ToArray(); | |
public static readonly IEnumerable<T> Values = Enums.Select(x => x.Enum).ToArray(); | |
public string Name { get; } | |
public T Enum { get; } | |
} | |
public static class TypeSafeEnumExtensions | |
{ | |
public static T ToTypeSafeEnum<T>(this string name) where T : class | |
{ | |
return TypeSafeEnum<T>.Enums | |
.SingleOrDefault(x => x.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))?.Enum; | |
} | |
public static T ToTypeSafeEnum<T>(this string name, T defaultEnum) where T : class | |
{ | |
return TypeSafeEnum<T>.Enums | |
.SingleOrDefault(x => x.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))?.Enum ?? defaultEnum; | |
} | |
} | |
public static class TypeSafeEnumValuesFromTypeNameRetriever | |
{ | |
/// <summary> | |
/// Gets all the TypeSafeEnum Values for a given type name from a given assembly | |
/// </summary> | |
public static IEnumerable<object> Retrieve<TAnyTypeInTargetAssembly>(string name) | |
{ | |
var enums = Assembly | |
.GetAssembly(typeof(TAnyTypeInTargetAssembly)) | |
.GetExportedTypes() | |
.Where(x => x.IsClass) | |
.Where(x => | |
x.Name.Equals(name, StringComparison.OrdinalIgnoreCase) || | |
x.Name.Equals(name + "dto", StringComparison.OrdinalIgnoreCase)) | |
.OrderBy(x => x.Name) | |
.Select(GetTypeSafeEnumValuesFor) | |
.Where(x => x != null) | |
.SingleOrDefault(x => ((ICollection) x).Count > 0); | |
return (IEnumerable<object>)enums ?? Enumerable.Empty<object>(); | |
} | |
private static object GetTypeSafeEnumValuesFor(Type type) | |
{ | |
var unboundTypeSafeEnumType = typeof(TypeSafeEnum<>); | |
var boundTypeSafeEnumType = unboundTypeSafeEnumType.MakeGenericType(type); | |
return boundTypeSafeEnumType | |
.GetField("Values", BindingFlags.Public | BindingFlags.Static) | |
?.GetValue(null); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment