diff --git a/src/Discord.Net.Commands/Discord.Net.Commands.csproj b/src/Discord.Net.Commands/Discord.Net.Commands.csproj index 94e58acf..0f15ea79 100644 --- a/src/Discord.Net.Commands/Discord.Net.Commands.csproj +++ b/src/Discord.Net.Commands/Discord.Net.Commands.csproj @@ -19,4 +19,7 @@ + + + diff --git a/src/Discord.Net.Commands/Utilities/ReflectionUtils.cs b/src/Discord.Net.Commands/Utilities/ReflectionUtils.cs index 28984448..2dcec2d6 100644 --- a/src/Discord.Net.Commands/Utilities/ReflectionUtils.cs +++ b/src/Discord.Net.Commands/Utilities/ReflectionUtils.cs @@ -1,3 +1,4 @@ +using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; using System.Linq; @@ -21,11 +22,11 @@ namespace Discord.Commands { var args = new object[parameters.Length]; for (int i = 0; i < parameters.Length; i++) - args[i] = GetMember(commands, services, parameters[i].ParameterType, typeInfo); + args[i] = GetMember(commands, services, parameters[i].ParameterType, typeInfo, parameters[i].GetCustomAttributes()); var obj = InvokeConstructor(constructor, args, typeInfo); foreach (var property in properties) - property.SetValue(obj, GetMember(commands, services, property.PropertyType, typeInfo)); + property.SetValue(obj, GetMember(commands, services, property.PropertyType, typeInfo, null)); return obj; }; } @@ -64,13 +65,20 @@ namespace Discord.Commands } return result.ToArray(); } - private static object GetMember(CommandService commands, IServiceProvider services, Type memberType, TypeInfo ownerType) + private static object GetMember(CommandService commands, IServiceProvider services, Type memberType, TypeInfo ownerType, IEnumerable attributes) { if (memberType == typeof(CommandService)) return commands; if (memberType == typeof(IServiceProvider) || memberType == services.GetType()) return services; - var service = services.GetService(memberType); + + var keyedAttribute = attributes?.FirstOrDefault(x => x.GetType() == typeof(FromKeyedServicesAttribute)); + object service; + if (keyedAttribute != null) + service = services.GetKeyedServices(memberType, ((FromKeyedServicesAttribute)keyedAttribute).Key).First(); + else + service = services.GetService(memberType); + if (service != null) return service; throw new InvalidOperationException($"Failed to create \"{ownerType.FullName}\", dependency \"{memberType.Name}\" was not found."); diff --git a/src/Discord.Net.Interactions/Discord.Net.Interactions.csproj b/src/Discord.Net.Interactions/Discord.Net.Interactions.csproj index b205e0ae..fa7b6ae6 100644 --- a/src/Discord.Net.Interactions/Discord.Net.Interactions.csproj +++ b/src/Discord.Net.Interactions/Discord.Net.Interactions.csproj @@ -20,7 +20,7 @@ - + diff --git a/src/Discord.Net.Interactions/Utilities/ReflectionUtils.cs b/src/Discord.Net.Interactions/Utilities/ReflectionUtils.cs index 1d14f371..b401027f 100644 --- a/src/Discord.Net.Interactions/Utilities/ReflectionUtils.cs +++ b/src/Discord.Net.Interactions/Utilities/ReflectionUtils.cs @@ -1,3 +1,4 @@ +using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; using System.Linq; @@ -23,11 +24,11 @@ namespace Discord.Interactions { var args = new object[parameters.Length]; for (int i = 0; i < parameters.Length; i++) - args[i] = GetMember(commandService, services, parameters[i].ParameterType, typeInfo); + args[i] = GetMember(commandService, services, parameters[i].ParameterType, typeInfo, parameters[i].GetCustomAttributes()); var obj = InvokeConstructor(constructor, args, typeInfo); foreach (var property in properties) - property.SetValue(obj, GetMember(commandService, services, property.PropertyType, typeInfo)); + property.SetValue(obj, GetMember(commandService, services, property.PropertyType, typeInfo, null)); return obj; }; } @@ -66,13 +67,20 @@ namespace Discord.Interactions } return result.ToArray(); } - private static object GetMember(InteractionService commandService, IServiceProvider services, Type memberType, TypeInfo ownerType) + private static object GetMember(InteractionService commandService, IServiceProvider services, Type memberType, TypeInfo ownerType, IEnumerable attributes) { if (memberType == typeof(InteractionService)) return commandService; if (memberType == typeof(IServiceProvider) || memberType == services.GetType()) return services; - var service = services.GetService(memberType); + + var keyedAttribute = attributes?.FirstOrDefault(x => x.GetType() == typeof(FromKeyedServicesAttribute)); + object service; + if (keyedAttribute != null) + service = services.GetKeyedServices(memberType, ((FromKeyedServicesAttribute)keyedAttribute).Key).First(); + else + service = services.GetService(memberType); + if (service != null) return service; throw new InvalidOperationException($"Failed to create \"{ownerType.FullName}\", dependency \"{memberType.Name}\" was not found."); @@ -119,10 +127,10 @@ namespace Discord.Interactions var props = new object[properties.Length]; for (int i = 0; i < parameters.Length; i++) - args[i] = GetMember(commandService, services, parameters[i].ParameterType, typeInfo); + args[i] = GetMember(commandService, services, parameters[i].ParameterType, typeInfo, parameters[i].GetCustomAttributes()); for (int i = 0; i < properties.Length; i++) - props[i] = GetMember(commandService, services, properties[i].PropertyType, typeInfo); + props[i] = GetMember(commandService, services, properties[i].PropertyType, typeInfo, null); var instance = lambda(args, props);