| @@ -114,7 +114,7 @@ namespace Discord.Commands.Builders | |||||
| return this; | return this; | ||||
| } | } | ||||
| private ModuleInfo BuildImpl(CommandService service, IServiceProvider services, ModuleInfo parent = null) | |||||
| private ModuleInfo BuildImpl(CommandService service, IServiceProvider services, IModuleFactory factory = null, ModuleInfo parent = null) | |||||
| { | { | ||||
| //Default name to first alias | //Default name to first alias | ||||
| if (Name == null) | if (Name == null) | ||||
| @@ -122,15 +122,15 @@ namespace Discord.Commands.Builders | |||||
| if (TypeInfo != null && !TypeInfo.IsAbstract) | if (TypeInfo != null && !TypeInfo.IsAbstract) | ||||
| { | { | ||||
| var moduleInstance = ReflectionUtils.CreateObject<IModuleBase>(TypeInfo, service, services); | |||||
| var moduleInstance = service.GetModuleFactory(TypeInfo, services, factory)(services); | |||||
| moduleInstance.OnModuleBuilding(service, this); | moduleInstance.OnModuleBuilding(service, this); | ||||
| } | } | ||||
| return new ModuleInfo(this, service, services, parent); | |||||
| return new ModuleInfo(this, service, services, factory, parent); | |||||
| } | } | ||||
| public ModuleInfo Build(CommandService service, IServiceProvider services) => BuildImpl(service, services); | public ModuleInfo Build(CommandService service, IServiceProvider services) => BuildImpl(service, services); | ||||
| internal ModuleInfo Build(CommandService service, IServiceProvider services, ModuleInfo parent) => BuildImpl(service, services, parent); | |||||
| internal ModuleInfo Build(CommandService service, IServiceProvider services, IModuleFactory factory, ModuleInfo parent) => BuildImpl(service, services, factory, parent); | |||||
| } | } | ||||
| } | } | ||||
| @@ -197,7 +197,7 @@ namespace Discord.Commands | |||||
| }); | }); | ||||
| } | } | ||||
| var createInstance = ReflectionUtils.CreateBuilder<IModuleBase>(typeInfo, service); | |||||
| var createInstance = service.GetModuleFactory(typeInfo, serviceprovider); | |||||
| async Task<IResult> ExecuteCallback(ICommandContext context, object[] args, IServiceProvider services, CommandInfo cmd) | async Task<IResult> ExecuteCallback(ICommandContext context, object[] args, IServiceProvider services, CommandInfo cmd) | ||||
| { | { | ||||
| @@ -151,6 +151,20 @@ namespace Discord.Commands | |||||
| } | } | ||||
| } | } | ||||
| internal Func<IServiceProvider, IModuleBase> GetModuleFactory(TypeInfo typeInfo, IServiceProvider services, IModuleFactory factory = null) | |||||
| { | |||||
| factory ??= (IModuleFactory)services.GetService(typeof(IModuleFactory)); | |||||
| if (factory != null) | |||||
| { | |||||
| return _ => (IModuleBase)factory.CreateBuilder(typeInfo, this)(); | |||||
| } | |||||
| else | |||||
| { | |||||
| return ReflectionUtils.CreateBuilder<IModuleBase>(typeInfo, this); | |||||
| } | |||||
| } | |||||
| /// <summary> | /// <summary> | ||||
| /// Add a command module from a <see cref="Type" />. | /// Add a command module from a <see cref="Type" />. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -0,0 +1,21 @@ | |||||
| using System; | |||||
| using System.Reflection; | |||||
| namespace Discord.Commands | |||||
| { | |||||
| /// <summary> | |||||
| /// Provides a custom logic for creating module instances. | |||||
| /// </summary> | |||||
| public interface IModuleFactory | |||||
| { | |||||
| /// <summary> | |||||
| /// Creates a builder function for the provided <see cref="TypeInfo" />. | |||||
| /// </summary> | |||||
| /// <param name="typeInfo">The module's type information.</param> | |||||
| /// <param name="commands">The <see cref="CommandService" /> that requested a new module instance.</param> | |||||
| /// <returns> | |||||
| /// A factory function for the provided module type. | |||||
| /// </returns> | |||||
| Func<object> CreateBuilder(TypeInfo typeInfo, CommandService commands); | |||||
| } | |||||
| } | |||||
| @@ -61,7 +61,7 @@ namespace Discord.Commands | |||||
| /// </summary> | /// </summary> | ||||
| public bool IsSubmodule => Parent != null; | public bool IsSubmodule => Parent != null; | ||||
| internal ModuleInfo(ModuleBuilder builder, CommandService service, IServiceProvider services, ModuleInfo parent = null) | |||||
| internal ModuleInfo(ModuleBuilder builder, CommandService service, IServiceProvider services, IModuleFactory moduleFactory, ModuleInfo parent = null) | |||||
| { | { | ||||
| Service = service; | Service = service; | ||||
| @@ -76,7 +76,7 @@ namespace Discord.Commands | |||||
| Preconditions = BuildPreconditions(builder).ToImmutableArray(); | Preconditions = BuildPreconditions(builder).ToImmutableArray(); | ||||
| Attributes = BuildAttributes(builder).ToImmutableArray(); | Attributes = BuildAttributes(builder).ToImmutableArray(); | ||||
| Submodules = BuildSubmodules(builder, service, services).ToImmutableArray(); | |||||
| Submodules = BuildSubmodules(builder, service, services, moduleFactory).ToImmutableArray(); | |||||
| } | } | ||||
| private static IEnumerable<string> BuildAliases(ModuleBuilder builder, CommandService service) | private static IEnumerable<string> BuildAliases(ModuleBuilder builder, CommandService service) | ||||
| @@ -106,12 +106,12 @@ namespace Discord.Commands | |||||
| return result; | return result; | ||||
| } | } | ||||
| private List<ModuleInfo> BuildSubmodules(ModuleBuilder parent, CommandService service, IServiceProvider services) | |||||
| private List<ModuleInfo> BuildSubmodules(ModuleBuilder parent, CommandService service, IServiceProvider services, IModuleFactory moduleFactory) | |||||
| { | { | ||||
| var result = new List<ModuleInfo>(); | var result = new List<ModuleInfo>(); | ||||
| foreach (var submodule in parent.Modules) | foreach (var submodule in parent.Modules) | ||||
| result.Add(submodule.Build(service, services, this)); | |||||
| result.Add(submodule.Build(service, services, moduleFactory, this)); | |||||
| return result; | return result; | ||||
| } | } | ||||