using System; using System.Linq; using System.Reflection; namespace FlowScope.Container { public static class ReflectionFactoryBuilder { public static void RegisterType(Container container) { if (container == null) { throw new ArgumentNullException(nameof(container)); } container.RegisterFactory(typeof(TImplementation), BuildFactory(typeof(TImplementation))); } public static void RegisterType(Container container) where TImplementation : TInterface { if (container == null) { throw new ArgumentNullException(nameof(container)); } container.RegisterFactory(typeof(TInterface), BuildFactory(typeof(TImplementation))); } public static Func BuildFactory(Type implementationType) { if (implementationType == null) { throw new ArgumentNullException(nameof(implementationType)); } if (!Attribute.IsDefined(implementationType, typeof(InjectableAttribute))) { throw new InvalidOperationException($"{FormatType(implementationType)} must be marked with InjectableAttribute for reflection registration."); } var constructors = implementationType.GetConstructors(BindingFlags.Public | BindingFlags.Instance); if (constructors.Length != 1) { throw new InvalidOperationException($"{FormatType(implementationType)} must declare exactly one public constructor."); } var constructor = constructors[0]; var parameters = constructor.GetParameters(); return container => { var arguments = parameters .Select(parameter => container.Resolve(parameter.ParameterType)) .ToArray(); return constructor.Invoke(arguments); }; } private static string FormatType(Type type) => type.FullName ?? type.Name; } }