Files
FlowScope/Packages/com.flowscope.gamecore/Runtime/Container/ReflectionFactoryBuilder.cs
2026-06-04 14:54:49 +08:00

63 lines
2.1 KiB
C#

using System;
using System.Linq;
using System.Reflection;
namespace FlowScope.Container
{
public static class ReflectionFactoryBuilder
{
public static void RegisterType<TImplementation>(Container container)
{
if (container == null)
{
throw new ArgumentNullException(nameof(container));
}
container.RegisterFactory(typeof(TImplementation), BuildFactory(typeof(TImplementation)));
}
public static void RegisterType<TInterface, TImplementation>(Container container)
where TImplementation : TInterface
{
if (container == null)
{
throw new ArgumentNullException(nameof(container));
}
container.RegisterFactory(typeof(TInterface), BuildFactory(typeof(TImplementation)));
}
public static Func<Container, object> 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;
}
}