@@ -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); | |||
} | |||
} |