diff --git a/src/Discord.Net.Commands/Builders/ModuleBuilder.cs b/src/Discord.Net.Commands/Builders/ModuleBuilder.cs index 0a33c9e26..67fb5904d 100644 --- a/src/Discord.Net.Commands/Builders/ModuleBuilder.cs +++ b/src/Discord.Net.Commands/Builders/ModuleBuilder.cs @@ -1,5 +1,6 @@ -using System; +using System; using System.Collections.Generic; +using System.Reflection; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; @@ -25,6 +26,8 @@ namespace Discord.Commands.Builders public IReadOnlyList Attributes => _attributes; public IReadOnlyList Aliases => _aliases; + internal Optional TypeInfo { get; set; } + //Automatic internal ModuleBuilder(CommandService service, ModuleBuilder parent) { diff --git a/src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs b/src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs index 5a3a1f25a..cf7b43555 100644 --- a/src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs +++ b/src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs @@ -98,6 +98,7 @@ namespace Discord.Commands private static void BuildModule(ModuleBuilder builder, TypeInfo typeInfo, CommandService service) { var attributes = typeInfo.GetCustomAttributes(); + builder.TypeInfo = typeInfo; foreach (var attribute in attributes) { diff --git a/src/Discord.Net.Commands/CommandService.cs b/src/Discord.Net.Commands/CommandService.cs index 8e7dab898..cb328bb55 100644 --- a/src/Discord.Net.Commands/CommandService.cs +++ b/src/Discord.Net.Commands/CommandService.cs @@ -1,5 +1,3 @@ -using Discord.Commands.Builders; -using Discord.Logging; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -8,6 +6,9 @@ using System.Linq; using System.Reflection; using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Discord.Commands.Builders; +using Discord.Logging; namespace Discord.Commands { @@ -93,8 +94,8 @@ namespace Discord.Commands _moduleLock.Release(); } } - public Task AddModuleAsync() => AddModuleAsync(typeof(T)); - public async Task AddModuleAsync(Type type) + public Task AddModuleAsync(IServiceProvider services = null) => AddModuleAsync(typeof(T), services); + public async Task AddModuleAsync(Type type, IServiceProvider services = null) { await _moduleLock.WaitAsync().ConfigureAwait(false); try @@ -111,14 +112,14 @@ namespace Discord.Commands _typedModuleDefs[module.Key] = module.Value; - return LoadModuleInternal(module.Value); + return LoadModuleInternal(module.Value, services); } finally { _moduleLock.Release(); } } - public async Task> AddModulesAsync(Assembly assembly) + public async Task> AddModulesAsync(Assembly assembly, IServiceProvider services = null) { await _moduleLock.WaitAsync().ConfigureAwait(false); try @@ -129,7 +130,7 @@ namespace Discord.Commands foreach (var info in moduleDefs) { _typedModuleDefs[info.Key] = info.Value; - LoadModuleInternal(info.Value); + LoadModuleInternal(info.Value, services); } return moduleDefs.Select(x => x.Value).ToImmutableArray(); @@ -139,10 +140,25 @@ namespace Discord.Commands _moduleLock.Release(); } } - private ModuleInfo LoadModuleInternal(ModuleInfo module) + private ModuleInfo LoadModuleInternal(ModuleInfo module, IServiceProvider services = null) { _moduleDefs.Add(module); + if (module.TypeInfo.IsSpecified) + { + services = services ?? EmptyServiceProvider.Instance; + try + { + var moduleInstance = ReflectionUtils.CreateObject(module.TypeInfo.Value, this, services); + moduleInstance.OnModuleAdded(this); + } + catch(Exception) + { + //unsure of what to do here + throw; + } + } + foreach (var command in module.Commands) _map.AddCommand(command); diff --git a/src/Discord.Net.Commands/IModuleBase.cs b/src/Discord.Net.Commands/IModuleBase.cs index 479724ae3..722c794c9 100644 --- a/src/Discord.Net.Commands/IModuleBase.cs +++ b/src/Discord.Net.Commands/IModuleBase.cs @@ -1,4 +1,4 @@ -namespace Discord.Commands +namespace Discord.Commands { internal interface IModuleBase { @@ -7,5 +7,7 @@ void BeforeExecute(CommandInfo command); void AfterExecute(CommandInfo command); + + void OnModuleAdded(CommandService commandService); } } diff --git a/src/Discord.Net.Commands/Info/ModuleInfo.cs b/src/Discord.Net.Commands/Info/ModuleInfo.cs index 97b90bf4e..e554391ea 100644 --- a/src/Discord.Net.Commands/Info/ModuleInfo.cs +++ b/src/Discord.Net.Commands/Info/ModuleInfo.cs @@ -2,7 +2,7 @@ using System; using System.Linq; using System.Collections.Generic; using System.Collections.Immutable; - +using System.Reflection; using Discord.Commands.Builders; namespace Discord.Commands @@ -22,6 +22,8 @@ namespace Discord.Commands public ModuleInfo Parent { get; } public bool IsSubmodule => Parent != null; + internal Optional TypeInfo { get; } + internal ModuleInfo(ModuleBuilder builder, CommandService service, ModuleInfo parent = null) { Service = service; @@ -31,6 +33,8 @@ namespace Discord.Commands Remarks = builder.Remarks; Parent = parent; + TypeInfo = builder.TypeInfo; + Aliases = BuildAliases(builder, service).ToImmutableArray(); Commands = builder.Commands.Select(x => x.Build(this, service)).ToImmutableArray(); Preconditions = BuildPreconditions(builder).ToImmutableArray(); diff --git a/src/Discord.Net.Commands/ModuleBase.cs b/src/Discord.Net.Commands/ModuleBase.cs index f51656e40..58cc3407c 100644 --- a/src/Discord.Net.Commands/ModuleBase.cs +++ b/src/Discord.Net.Commands/ModuleBase.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading.Tasks; namespace Discord.Commands @@ -23,6 +23,10 @@ namespace Discord.Commands { } + protected virtual void OnModuleAdded(CommandService commandService) + { + } + //IModuleBase void IModuleBase.SetContext(ICommandContext context) { @@ -33,5 +37,7 @@ namespace Discord.Commands void IModuleBase.BeforeExecute(CommandInfo command) => BeforeExecute(command); void IModuleBase.AfterExecute(CommandInfo command) => AfterExecute(command); + + void IModuleBase.OnModuleAdded(CommandService commandService) => OnModuleAdded(commandService); } }