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