diff --git a/src/Discord.Net.Commands/Dependencies/DependencyMap.cs b/src/Discord.Net.Commands/Dependencies/DependencyMap.cs index ba5995f26..f5adf1a8c 100644 --- a/src/Discord.Net.Commands/Dependencies/DependencyMap.cs +++ b/src/Discord.Net.Commands/Dependencies/DependencyMap.cs @@ -5,27 +5,59 @@ namespace Discord.Commands { public class DependencyMap : IDependencyMap { - private Dictionary map; + private Dictionary> map; public static DependencyMap Empty => new DependencyMap(); public DependencyMap() { - map = new Dictionary(); + map = new Dictionary>(); } - public void Add(T obj) + /// + public void Add(T obj) where T : class + => AddFactory(() => obj); + /// + public bool TryAdd(T obj) where T : class + => TryAddFactory(() => obj); + /// + public void AddTransient() where T : class, new() + => AddFactory(() => new T()); + /// + public bool TryAddTransient() where T : class, new() + => TryAddFactory(() => new T()); + /// + public void AddTransient() where TKey : class + where TImpl : class, TKey, new() + => AddFactory(() => new TImpl()); + public bool TryAddTransient() where TKey : class + where TImpl : class, TKey, new() + => TryAddFactory(() => new TImpl()); + + /// + public void AddFactory(Func factory) where T : class { var t = typeof(T); if (map.ContainsKey(t)) throw new InvalidOperationException($"The dependency map already contains \"{t.FullName}\""); - map.Add(t, obj); + map.Add(t, factory); + } + /// + public bool TryAddFactory(Func factory) where T : class + { + var t = typeof(T); + if (map.ContainsKey(t)) + return false; + map.Add(t, factory); + return true; } + /// public T Get() { return (T)Get(typeof(T)); } + /// public object Get(Type t) { object result; @@ -35,6 +67,7 @@ namespace Discord.Commands return result; } + /// public bool TryGet(out T result) { object untypedResult; @@ -49,9 +82,17 @@ namespace Discord.Commands return false; } } + /// public bool TryGet(Type t, out object result) { - return map.TryGetValue(t, out result); + Func func; + if (map.TryGetValue(t, out func)) + { + result = func(); + return true; + } + result = null; + return false; } } } diff --git a/src/Discord.Net.Commands/Dependencies/IDependencyMap.cs b/src/Discord.Net.Commands/Dependencies/IDependencyMap.cs index 784a9bc56..a55a9e4c5 100644 --- a/src/Discord.Net.Commands/Dependencies/IDependencyMap.cs +++ b/src/Discord.Net.Commands/Dependencies/IDependencyMap.cs @@ -4,12 +4,86 @@ namespace Discord.Commands { public interface IDependencyMap { - void Add(T obj); + /// + /// Add an instance of a service to be injected. + /// + /// The type of service. + /// The instance of a service. + void Add(T obj) where T : class; + /// + /// Tries to add an instance of a service to be injected. + /// + /// The type of service. + /// The instance of a service. + /// A bool, indicating if the service was successfully added to the DependencyMap. + bool TryAdd(T obj) where T : class; + /// + /// Add a service that will be injected by a new instance every time. + /// + /// The type of instance to inject. + void AddTransient() where T : class, new(); + /// + /// Tries to add a service that will be injected by a new instance every time. + /// + /// The type of instance to inject. + /// A bool, indicating if the service was successfully added to the DependencyMap. + bool TryAddTransient() where T : class, new(); + /// + /// Add a service that will be injected by a new instance every time. + /// + /// The type to look for when injecting. + /// The type to inject when injecting. + /// + /// map.AddTransient<IService, Service> + /// + void AddTransient() where TKey: class where TImpl : class, TKey, new(); + /// + /// Tries to add a service that will be injected by a new instance every time. + /// + /// The type to look for when injecting. + /// The type to inject when injecting. + /// A bool, indicating if the service was successfully added to the DependencyMap. + bool TryAddTransient() where TKey : class where TImpl : class, TKey, new(); + /// + /// Add a service that will be injected by a factory. + /// + /// The type to look for when injecting. + /// The factory that returns a type of this service. + void AddFactory(Func factory) where T : class; + /// + /// Tries to add a service that will be injected by a factory. + /// + /// The type to look for when injecting. + /// The factory that returns a type of this service. + /// A bool, indicating if the service was successfully added to the DependencyMap. + bool TryAddFactory(Func factory) where T : class; + /// + /// Pull an object from the map. + /// + /// The type of service. + /// An instance of this service. T Get(); + /// + /// Try to pull an object from the map. + /// + /// The type of service. + /// The instance of this service. + /// Whether or not this object could be found in the map. bool TryGet(out T result); + /// + /// Pull an object from the map. + /// + /// The type of service. + /// An instance of this service. object Get(Type t); + /// + /// Try to pull an object from the map. + /// + /// The type of service. + /// An instance of this service. + /// Whether or not this object could be found in the map. bool TryGet(Type t, out object result); } } diff --git a/src/Discord.Net.Commands/Utilities/ReflectionUtils.cs b/src/Discord.Net.Commands/Utilities/ReflectionUtils.cs index 27ea601bf..1923734e7 100644 --- a/src/Discord.Net.Commands/Utilities/ReflectionUtils.cs +++ b/src/Discord.Net.Commands/Utilities/ReflectionUtils.cs @@ -42,7 +42,8 @@ namespace Discord.Commands try { - return (T)constructor.Invoke(args); + T instance = (T)constructor.Invoke(args); + return instance; } catch (Exception ex) {