using System; using System.Collections.Generic; namespace SmallInjector { /// /// A small dependency injector to demonstrate the pattern. /// public class Container : IContainer { private readonly Dictionary _container = new Dictionary(); /// public void RegisterType(bool isSingleton, TService instance = default) where TService : TInterface { _container.Add(typeof(TInterface), new RegisteredType(typeof(TService), isSingleton, null)); } /// public void RegisterType(bool isSingleton, TService instance = default) => RegisterType(isSingleton, instance); /// public TService Resolve() => (TService) Resolve(typeof(TService)); /// public bool IsRegistered() => IsRegistered(typeof(TService)); /// public bool IsRegistered(Type serviceType) => _container.ContainsKey(serviceType); /// public object Resolve(Type serviceInterface) { if (!_container.TryGetValue(serviceInterface, out var registeredType)) throw new Exception(@"Dependency {serviceInterface} is not registered"); 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 bool IsSingleton { get; } public Type ServiceType { get; } public object Instance { get; set; } public RegisteredType(Type serviceType, bool isSingleton, object instance) { ServiceType = serviceType; IsSingleton = isSingleton; Instance = instance; } } } }