| @@ -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<Attribute> Attributes => _attributes; | |||
| public IReadOnlyList<string> Aliases => _aliases; | |||
| internal Optional<TypeInfo> TypeInfo { get; set; } | |||
| //Automatic | |||
| internal ModuleBuilder(CommandService service, ModuleBuilder parent) | |||
| { | |||
| @@ -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) | |||
| { | |||
| @@ -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<ModuleInfo> AddModuleAsync<T>() => AddModuleAsync(typeof(T)); | |||
| public async Task<ModuleInfo> AddModuleAsync(Type type) | |||
| public Task<ModuleInfo> AddModuleAsync<T>(IServiceProvider services = null) => AddModuleAsync(typeof(T), services); | |||
| public async Task<ModuleInfo> 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<IEnumerable<ModuleInfo>> AddModulesAsync(Assembly assembly) | |||
| public async Task<IEnumerable<ModuleInfo>> 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<IModuleBase>(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); | |||
| @@ -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); | |||
| } | |||
| } | |||
| @@ -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> 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(); | |||
| @@ -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); | |||
| } | |||
| } | |||