@@ -114,7 +114,7 @@ namespace Discord.Commands.Builders | |||
return this; | |||
} | |||
private ModuleInfo BuildImpl(CommandService service, ModuleInfo parent = null) | |||
private ModuleInfo BuildImpl(CommandService service, IServiceProvider services, ModuleInfo parent = null) | |||
{ | |||
//Default name to first alias | |||
if (Name == null) | |||
@@ -124,7 +124,7 @@ namespace Discord.Commands.Builders | |||
{ | |||
try | |||
{ | |||
var moduleInstance = ReflectionUtils.CreateObject<IModuleBase>(TypeInfo, service, service._serviceProvider); | |||
var moduleInstance = ReflectionUtils.CreateObject<IModuleBase>(TypeInfo, service, services); | |||
moduleInstance.OnModuleBuilding(service); | |||
} | |||
catch (Exception) | |||
@@ -134,11 +134,11 @@ namespace Discord.Commands.Builders | |||
} | |||
} | |||
return new ModuleInfo(this, service, parent); | |||
return new ModuleInfo(this, service, services, parent); | |||
} | |||
public ModuleInfo Build(CommandService service) => BuildImpl(service); | |||
public ModuleInfo Build(CommandService service, IServiceProvider services) => BuildImpl(service, services); | |||
internal ModuleInfo Build(CommandService service, ModuleInfo parent) => BuildImpl(service, parent); | |||
internal ModuleInfo Build(CommandService service, IServiceProvider services, ModuleInfo parent) => BuildImpl(service, services, parent); | |||
} | |||
} |
@@ -42,8 +42,8 @@ namespace Discord.Commands | |||
} | |||
public static Task<Dictionary<Type, ModuleInfo>> BuildAsync(CommandService service, params TypeInfo[] validTypes) => BuildAsync(validTypes, service); | |||
public static async Task<Dictionary<Type, ModuleInfo>> BuildAsync(IEnumerable<TypeInfo> validTypes, CommandService service) | |||
public static Task<Dictionary<Type, ModuleInfo>> BuildAsync(CommandService service, IServiceProvider services, params TypeInfo[] validTypes) => BuildAsync(validTypes, service, services); | |||
public static async Task<Dictionary<Type, ModuleInfo>> BuildAsync(IEnumerable<TypeInfo> validTypes, CommandService service, IServiceProvider services) | |||
{ | |||
/*if (!validTypes.Any()) | |||
throw new InvalidOperationException("Could not find any valid modules from the given selection");*/ | |||
@@ -63,11 +63,11 @@ namespace Discord.Commands | |||
var module = new ModuleBuilder(service, null); | |||
BuildModule(module, typeInfo, service); | |||
BuildSubTypes(module, typeInfo.DeclaredNestedTypes, builtTypes, service); | |||
BuildModule(module, typeInfo, service, services); | |||
BuildSubTypes(module, typeInfo.DeclaredNestedTypes, builtTypes, service, services); | |||
builtTypes.Add(typeInfo); | |||
result[typeInfo.AsType()] = module.Build(service); | |||
result[typeInfo.AsType()] = module.Build(service, services); | |||
} | |||
await service._cmdLogger.DebugAsync($"Successfully built {builtTypes.Count} modules.").ConfigureAwait(false); | |||
@@ -75,7 +75,7 @@ namespace Discord.Commands | |||
return result; | |||
} | |||
private static void BuildSubTypes(ModuleBuilder builder, IEnumerable<TypeInfo> subTypes, List<TypeInfo> builtTypes, CommandService service) | |||
private static void BuildSubTypes(ModuleBuilder builder, IEnumerable<TypeInfo> subTypes, List<TypeInfo> builtTypes, CommandService service, IServiceProvider services) | |||
{ | |||
foreach (var typeInfo in subTypes) | |||
{ | |||
@@ -87,15 +87,15 @@ namespace Discord.Commands | |||
builder.AddModule((module) => | |||
{ | |||
BuildModule(module, typeInfo, service); | |||
BuildSubTypes(module, typeInfo.DeclaredNestedTypes, builtTypes, service); | |||
BuildModule(module, typeInfo, service, services); | |||
BuildSubTypes(module, typeInfo.DeclaredNestedTypes, builtTypes, service, services); | |||
}); | |||
builtTypes.Add(typeInfo); | |||
} | |||
} | |||
private static void BuildModule(ModuleBuilder builder, TypeInfo typeInfo, CommandService service) | |||
private static void BuildModule(ModuleBuilder builder, TypeInfo typeInfo, CommandService service, IServiceProvider services) | |||
{ | |||
var attributes = typeInfo.GetCustomAttributes(); | |||
builder.TypeInfo = typeInfo; | |||
@@ -141,12 +141,12 @@ namespace Discord.Commands | |||
{ | |||
builder.AddCommand((command) => | |||
{ | |||
BuildCommand(command, typeInfo, method, service); | |||
BuildCommand(command, typeInfo, method, service, services); | |||
}); | |||
} | |||
} | |||
private static void BuildCommand(CommandBuilder builder, TypeInfo typeInfo, MethodInfo method, CommandService service) | |||
private static void BuildCommand(CommandBuilder builder, TypeInfo typeInfo, MethodInfo method, CommandService service, IServiceProvider serviceprovider) | |||
{ | |||
var attributes = method.GetCustomAttributes(); | |||
@@ -192,7 +192,7 @@ namespace Discord.Commands | |||
{ | |||
builder.AddParameter((parameter) => | |||
{ | |||
BuildParameter(parameter, paramInfo, pos++, count, service); | |||
BuildParameter(parameter, paramInfo, pos++, count, service, serviceprovider); | |||
}); | |||
} | |||
@@ -228,7 +228,7 @@ namespace Discord.Commands | |||
builder.Callback = ExecuteCallback; | |||
} | |||
private static void BuildParameter(ParameterBuilder builder, System.Reflection.ParameterInfo paramInfo, int position, int count, CommandService service) | |||
private static void BuildParameter(ParameterBuilder builder, System.Reflection.ParameterInfo paramInfo, int position, int count, CommandService service, IServiceProvider services) | |||
{ | |||
var attributes = paramInfo.GetCustomAttributes(); | |||
var paramType = paramInfo.ParameterType; | |||
@@ -246,7 +246,7 @@ namespace Discord.Commands | |||
builder.Summary = summary.Text; | |||
break; | |||
case OverrideTypeReaderAttribute typeReader: | |||
builder.TypeReader = GetTypeReader(service, paramType, typeReader.TypeReader); | |||
builder.TypeReader = GetTypeReader(service, paramType, typeReader.TypeReader, services); | |||
break; | |||
case ParamArrayAttribute _: | |||
builder.IsMultiple = true; | |||
@@ -286,7 +286,7 @@ namespace Discord.Commands | |||
} | |||
} | |||
private static TypeReader GetTypeReader(CommandService service, Type paramType, Type typeReaderType) | |||
private static TypeReader GetTypeReader(CommandService service, Type paramType, Type typeReaderType, IServiceProvider services) | |||
{ | |||
var readers = service.GetTypeReaders(paramType); | |||
TypeReader reader = null; | |||
@@ -297,7 +297,7 @@ namespace Discord.Commands | |||
} | |||
//We dont have a cached type reader, create one | |||
reader = ReflectionUtils.CreateObject<TypeReader>(typeReaderType.GetTypeInfo(), service, service._serviceProvider); | |||
reader = ReflectionUtils.CreateObject<TypeReader>(typeReaderType.GetTypeInfo(), service, services); | |||
service.AddTypeReader(paramType, reader); | |||
return reader; | |||
@@ -28,7 +28,7 @@ namespace Discord.Commands | |||
private readonly HashSet<ModuleInfo> _moduleDefs; | |||
private readonly CommandMap _map; | |||
internal readonly IServiceProvider _serviceProvider; | |||
//internal readonly IServiceProvider _serviceProvider; | |||
internal readonly bool _caseSensitive, _throwOnError, _ignoreExtraArgs; | |||
internal readonly char _separatorChar; | |||
@@ -43,10 +43,6 @@ namespace Discord.Commands | |||
public CommandService() : this(new CommandServiceConfig()) { } | |||
public CommandService(CommandServiceConfig config) | |||
{ | |||
_serviceProvider = config.ServiceProvider | |||
?? config.ServiceProviderFactory?.Invoke(this) | |||
?? EmptyServiceProvider.Instance; | |||
_caseSensitive = config.CaseSensitiveCommands; | |||
_throwOnError = config.ThrowOnError; | |||
_ignoreExtraArgs = config.IgnoreExtraArgs; | |||
@@ -81,6 +77,10 @@ namespace Discord.Commands | |||
entityTypeReaders.Add(new Tuple<Type, Type>(typeof(IRole), typeof(RoleTypeReader<>))); | |||
entityTypeReaders.Add(new Tuple<Type, Type>(typeof(IUser), typeof(UserTypeReader<>))); | |||
_entityTypeReaders = entityTypeReaders.ToImmutable(); | |||
//_serviceProvider = config.ServiceProvider | |||
// ?? config.ServiceProviderFactory?.Invoke(this) | |||
// ?? EmptyServiceProvider.Instance; | |||
} | |||
//Modules | |||
@@ -101,8 +101,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) => AddModuleAsync(typeof(T), services); | |||
public async Task<ModuleInfo> AddModuleAsync(Type type, IServiceProvider services) | |||
{ | |||
await _moduleLock.WaitAsync().ConfigureAwait(false); | |||
try | |||
@@ -112,7 +112,7 @@ namespace Discord.Commands | |||
if (_typedModuleDefs.ContainsKey(type)) | |||
throw new ArgumentException($"This module has already been added."); | |||
var module = (await ModuleClassBuilder.BuildAsync(this, typeInfo).ConfigureAwait(false)).FirstOrDefault(); | |||
var module = (await ModuleClassBuilder.BuildAsync(this, services, typeInfo).ConfigureAwait(false)).FirstOrDefault(); | |||
if (module.Value == default(ModuleInfo)) | |||
throw new InvalidOperationException($"Could not build the module {type.FullName}, did you pass an invalid type?"); | |||
@@ -126,13 +126,13 @@ namespace Discord.Commands | |||
_moduleLock.Release(); | |||
} | |||
} | |||
public async Task<IEnumerable<ModuleInfo>> AddModulesAsync(Assembly assembly) | |||
public async Task<IEnumerable<ModuleInfo>> AddModulesAsync(Assembly assembly, IServiceProvider services) | |||
{ | |||
await _moduleLock.WaitAsync().ConfigureAwait(false); | |||
try | |||
{ | |||
var types = await ModuleClassBuilder.SearchAsync(assembly, this).ConfigureAwait(false); | |||
var moduleDefs = await ModuleClassBuilder.BuildAsync(types, this).ConfigureAwait(false); | |||
var moduleDefs = await ModuleClassBuilder.BuildAsync(types, this, services).ConfigureAwait(false); | |||
foreach (var info in moduleDefs) | |||
{ | |||
@@ -280,12 +280,13 @@ namespace Discord.Commands | |||
return SearchResult.FromError(CommandError.UnknownCommand, "Unknown command."); | |||
} | |||
public Task<IResult> ExecuteAsync(ICommandContext context, int argPos, /*IServiceProvider services = null,*/ MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) | |||
=> ExecuteAsync(context, context.Message.Content.Substring(argPos), /*services,*/ multiMatchHandling); | |||
public async Task<IResult> ExecuteAsync(ICommandContext context, string input, /*IServiceProvider services = null,*/ MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) | |||
public Task<IResult> ExecuteAsync(ICommandContext context, int argPos, IServiceProvider services = null, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) | |||
=> ExecuteAsync(context, context.Message.Content.Substring(argPos), services, multiMatchHandling); | |||
public async Task<IResult> ExecuteAsync(ICommandContext context, string input, IServiceProvider services = null, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) | |||
{ | |||
//services = services ?? EmptyServiceProvider.Instance; | |||
using (var scope = _serviceProvider.CreateScope()) | |||
services = services ?? EmptyServiceProvider.Instance; | |||
//using (var scope = _serviceProvider.CreateScope()) | |||
using (var scope = services.CreateScope()) | |||
{ | |||
var searchResult = Search(context, input); | |||
if (!searchResult.IsSuccess) | |||
@@ -21,10 +21,10 @@ namespace Discord.Commands | |||
/// <summary> Determines whether extra parameters should be ignored. </summary> | |||
public bool IgnoreExtraArgs { get; set; } = false; | |||
/// <summary> Gets or sets the <see cref="IServiceProvider"/> to use. </summary> | |||
public IServiceProvider ServiceProvider { get; set; } = null; | |||
///// <summary> Gets or sets the <see cref="IServiceProvider"/> to use. </summary> | |||
//public IServiceProvider ServiceProvider { get; set; } = null; | |||
/// <summary> Gets or sets a factory function for the <see cref="IServiceProvider"/> to use. </summary> | |||
public Func<CommandService, IServiceProvider> ServiceProviderFactory { get; set; } = null; | |||
///// <summary> Gets or sets a factory function for the <see cref="IServiceProvider"/> to use. </summary> | |||
//public Func<CommandService, IServiceProvider> ServiceProviderFactory { get; set; } = null; | |||
} | |||
} |
@@ -24,7 +24,7 @@ namespace Discord.Commands | |||
//public TypeInfo TypeInfo { get; } | |||
internal ModuleInfo(ModuleBuilder builder, CommandService service, ModuleInfo parent = null) | |||
internal ModuleInfo(ModuleBuilder builder, CommandService service, IServiceProvider services, ModuleInfo parent = null) | |||
{ | |||
Service = service; | |||
@@ -40,7 +40,7 @@ namespace Discord.Commands | |||
Preconditions = BuildPreconditions(builder).ToImmutableArray(); | |||
Attributes = BuildAttributes(builder).ToImmutableArray(); | |||
Submodules = BuildSubmodules(builder, service).ToImmutableArray(); | |||
Submodules = BuildSubmodules(builder, service, services).ToImmutableArray(); | |||
} | |||
private static IEnumerable<string> BuildAliases(ModuleBuilder builder, CommandService service) | |||
@@ -70,12 +70,12 @@ namespace Discord.Commands | |||
return result; | |||
} | |||
private List<ModuleInfo> BuildSubmodules(ModuleBuilder parent, CommandService service) | |||
private List<ModuleInfo> BuildSubmodules(ModuleBuilder parent, CommandService service, IServiceProvider services) | |||
{ | |||
var result = new List<ModuleInfo>(); | |||
foreach (var submodule in parent.Modules) | |||
result.Add(submodule.Build(service, this)); | |||
result.Add(submodule.Build(service, services, this)); | |||
return result; | |||
} | |||