using System; using System.Collections.Generic; using System.Reflection; namespace BracerLib.DI { public class DependencyProvider { private IDictionary dependencyMap = new Dictionary(); private IDictionary singletons = new Dictionary(); public DependencyProvider(DependencyCollection collection) { foreach (var d in collection) dependencyMap.Add(d.Type, d); } public object Get(Type type) { if (!dependencyMap.ContainsKey(type)) throw new ArgumentException($"Type is not a dependency: {type.FullName}"); var dependency = dependencyMap[type]; switch (dependency.Lifetime) { case DependencyLifetime.Transient: return dependency.Factory(this); case DependencyLifetime.Singleton: if (!singletons.ContainsKey(type)) singletons.Add(type, dependency.Factory(this)); return singletons[type]; default: throw new ArgumentOutOfRangeException($"Unavailable lifetime for dependency: {type.FullName}"); } } public T Get() => (T)Get(typeof(T)); public object Inject(object dependant) { var type = dependant.GetType(); while (type != null) { var fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.Instance); foreach (var f in fields) { if (f.GetCustomAttribute(false) == null) continue; f.SetValue(dependant, Get(f.FieldType)); } type = type.BaseType; } return dependant; } } }