diff --git a/src/Discord.Net.Commands/Builders/ModuleBuilder.cs b/src/Discord.Net.Commands/Builders/ModuleBuilder.cs index 6dc50db31..63611c204 100644 --- a/src/Discord.Net.Commands/Builders/ModuleBuilder.cs +++ b/src/Discord.Net.Commands/Builders/ModuleBuilder.cs @@ -114,7 +114,7 @@ namespace Discord.Commands.Builders 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 if (Name == null) @@ -122,15 +122,15 @@ namespace Discord.Commands.Builders if (TypeInfo != null && !TypeInfo.IsAbstract) { - var moduleInstance = ReflectionUtils.CreateObject(TypeInfo, service, services); + var moduleInstance = service.GetModuleFactory(TypeInfo, services, factory)(services); 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); - 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); } } diff --git a/src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs b/src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs index aec8dcbe3..0b70114b1 100644 --- a/src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs +++ b/src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs @@ -197,7 +197,7 @@ namespace Discord.Commands }); } - var createInstance = ReflectionUtils.CreateBuilder(typeInfo, service); + var createInstance = service.GetModuleFactory(typeInfo, serviceprovider); async Task ExecuteCallback(ICommandContext context, object[] args, IServiceProvider services, CommandInfo cmd) { diff --git a/src/Discord.Net.Commands/CommandService.cs b/src/Discord.Net.Commands/CommandService.cs index 1d4b0e15a..5464e8188 100644 --- a/src/Discord.Net.Commands/CommandService.cs +++ b/src/Discord.Net.Commands/CommandService.cs @@ -151,6 +151,20 @@ namespace Discord.Commands } } + internal Func 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(typeInfo, this); + } + } + /// /// Add a command module from a . /// diff --git a/src/Discord.Net.Commands/IModuleFactory.cs b/src/Discord.Net.Commands/IModuleFactory.cs new file mode 100644 index 000000000..240a3a07c --- /dev/null +++ b/src/Discord.Net.Commands/IModuleFactory.cs @@ -0,0 +1,21 @@ +using System; +using System.Reflection; + +namespace Discord.Commands +{ + /// + /// Provides a custom logic for creating module instances. + /// + public interface IModuleFactory + { + /// + /// Creates a builder function for the provided . + /// + /// The module's type information. + /// The that requested a new module instance. + /// + /// A factory function for the provided module type. + /// + Func CreateBuilder(TypeInfo typeInfo, CommandService commands); + } +} diff --git a/src/Discord.Net.Commands/Info/ModuleInfo.cs b/src/Discord.Net.Commands/Info/ModuleInfo.cs index 7b9959efe..fa15c5e18 100644 --- a/src/Discord.Net.Commands/Info/ModuleInfo.cs +++ b/src/Discord.Net.Commands/Info/ModuleInfo.cs @@ -61,7 +61,7 @@ namespace Discord.Commands /// 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; @@ -76,7 +76,7 @@ namespace Discord.Commands Preconditions = BuildPreconditions(builder).ToImmutableArray(); Attributes = BuildAttributes(builder).ToImmutableArray(); - Submodules = BuildSubmodules(builder, service, services).ToImmutableArray(); + Submodules = BuildSubmodules(builder, service, services, moduleFactory).ToImmutableArray(); } private static IEnumerable BuildAliases(ModuleBuilder builder, CommandService service) @@ -106,12 +106,12 @@ namespace Discord.Commands return result; } - private List BuildSubmodules(ModuleBuilder parent, CommandService service, IServiceProvider services) + private List BuildSubmodules(ModuleBuilder parent, CommandService service, IServiceProvider services, IModuleFactory moduleFactory) { var result = new List(); foreach (var submodule in parent.Modules) - result.Add(submodule.Build(service, services, this)); + result.Add(submodule.Build(service, services, moduleFactory, this)); return result; }