public class MyContainer { private readonly Dictionary<Type, object> services = new Dictionary<Type, object>(); public void Register<T>(T service) { services[typeof(T)] = service; } public T Resolve<T>() { return (T)Resolve(typeof(T)); } private object Resolve(Type type) { if (services.TryGetValue(type, out object service)) { return service; } if (type.IsAbstract || type.IsInterface) { throw new InvalidOperationException($"Cannot resolve {type.FullName}."); } ConstructorInfo[] ctors = type.GetConstructors(); if (ctors.Length != 1) { throw new InvalidOperationException($"Type {type.FullName} must have a single constructor."); } ConstructorInfo ctor = ctors[0]; ParameterInfo[] parameters = ctor.GetParameters(); object[] args = new object[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { args[i] = Resolve(parameters[i].ParameterType); } return Activator.CreateInstance(type, args); } }
第二种反射写法
public class MyContainer { private readonly Dictionary<Type, Type> _registrations = new Dictionary<Type, Type>(); public void Register<TFrom, TTo>() where TTo : TFrom { _registrations[typeof(TFrom)] = typeof(TTo); } public T Resolve<T>() { return (T)Resolve(typeof(T)); } private object Resolve(Type type) { Type implementationType = GetImplementationType(type); ConstructorInfo ctor = implementationType.GetConstructors()[0]; ParameterInfo[] parameters = ctor.GetParameters(); object[] arguments = parameters.Select(p => Resolve(p.ParameterType)).ToArray(); return Activator.CreateInstance(implementationType, arguments); } private Type GetImplementationType(Type interfaceType) { if (!_registrations.TryGetValue(interfaceType, out Type implementationType)) { implementationType = interfaceType; } if (!implementationType.IsInterface && !implementationType.IsAbstract) { return implementationType; } Type[] types = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(s => s.GetTypes()) .Where(p => interfaceType.IsAssignableFrom(p) && !p.IsAbstract) .ToArray(); if (types.Length > 1) { throw new InvalidOperationException($"Too many implementations of interface {interfaceType.FullName} found."); } if (types.Length == 0) { throw new InvalidOperationException($"No implementation of interface {interfaceType.FullName} found."); } return types[0]; } }