using System; using System.Collections.Generic; namespace SmallInjectorDemo { /// /// A small dependency injector to demonstrate the pattern. /// public class SmallInjector { private readonly Dictionary _container = new Dictionary(); /// /// Register types in the resolve container. /// /// Type of the service. /// Type of the interface of the service. /// True if the service should be singleton. False otherwise. /// instance of the service public void RegisterType(bool isSingleton, TService instance = default(TService)) { _container.Add(typeof(TInterface), new RegisteredType(typeof(TService), isSingleton, null)); } /// /// Register types in the resolve container. /// /// Type of the service. public void RegisterType(bool isSingleton, TService instance = default(TService)) => RegisterType(isSingleton, instance); /// /// Resolve service of specified type. /// /// Type of the service. /// A instance of the service. public TService Resolve() => (TService)Resolve(typeof(TService)); /// /// Resolve service of specified type. /// /// Type of the service. /// A instance of the service. public object Resolve(Type serviceInterface) { if (!_container.TryGetValue(serviceInterface, out var registeredType)) throw new Exception("Can't resolve dependency " + serviceInterface); if (registeredType.IsSingleton && registeredType.Instance != null) return registeredType.Instance; var constructor = registeredType.ServiceType.GetConstructors()[0]; var parameters = constructor.GetParameters(); var constructorParameters = new object[parameters.Length]; for (var i = 0; i < parameters.Length; i++) { constructorParameters[i] = Resolve(parameters[i].ParameterType); } var instance = constructor.Invoke(constructorParameters); return registeredType.IsSingleton ? (registeredType.Instance = instance) : instance; } private class RegisteredType { public RegisteredType(Type serviceType, bool isSingleton, object instance) { ServiceType = serviceType; IsSingleton = isSingleton; Instance = instance; } public readonly bool IsSingleton; public readonly Type ServiceType; public object Instance { get; set; } } } }