Skip to content

Instantly share code, notes, and snippets.

@blam23
Created February 26, 2023 18:35
Show Gist options
  • Select an option

  • Save blam23/826b71a8779201688c948b6708d92ba0 to your computer and use it in GitHub Desktop.

Select an option

Save blam23/826b71a8779201688c948b6708d92ba0 to your computer and use it in GitHub Desktop.
Generic Class Factory
using System.Reflection;
namespace GenericInitialiserTest
{
public static class GenericClassFactory
{
public static readonly Dictionary<Type, Type> Classes = new();
public static void RegisterAllGenerics(Assembly assembly)
{
var types = assembly.GetTypes();
foreach (var type in types)
{
var bt = type.BaseType;
if (bt != null)
{
if (bt.IsGenericType &&
bt.GetGenericTypeDefinition() == typeof(GenericClass<>))
{
var innerTypes = bt.GetGenericArguments();
if (innerTypes.Length == 1)
Register(innerTypes[0], type);
}
}
}
}
public static void Register(Type innerType, Type genericClass)
{
if (Classes.ContainsKey(innerType))
throw new InvalidProgramException($"Duplicate GenericClass for type: {innerType}");
Classes.Add(innerType, genericClass);
Console.WriteLine($"Reigstered for type: {innerType}");
}
// This just returns the Type - could be updated to create a new instance instead
public static Type? GetGenericClassFor<T>()
{
if (Classes.TryGetValue(typeof(T), out var t))
return t;
return null;
}
}
public abstract class GenericClass<T>
{
private readonly T _instance;
public T Instance => _instance;
internal GenericClass(T instance)
{
_instance = instance;
}
}
}
namespace GenericInitialiserTest
{
class GenericFloat : GenericClass<float>
{
public GenericFloat(float f) : base(f) { }
}
class GenericString : GenericClass<string>
{
public GenericString(string s) : base(s) { }
}
}
using GenericInitialiserTest;
using System.Reflection;
// Can register either current assembly or loaded assemblies (such as external DLLs)
GenericClassFactory.RegisterAllGenerics(Assembly.GetExecutingAssembly());
GenericFloat f = new(4.5f);
Console.WriteLine($"Class for float = {GenericClassFactory.GetGenericClassFor<float>()}");
Console.WriteLine($"Class for string = {GenericClassFactory.GetGenericClassFor<string>()}");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment