Browse Source

Add support for custom module instantiation logic

pull/1519/head
Stanislav Skobelkin 5 years ago
parent
commit
d1822bc209
5 changed files with 44 additions and 9 deletions
  1. +4
    -4
      src/Discord.Net.Commands/Builders/ModuleBuilder.cs
  2. +1
    -1
      src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs
  3. +14
    -0
      src/Discord.Net.Commands/CommandService.cs
  4. +21
    -0
      src/Discord.Net.Commands/IModuleFactory.cs
  5. +4
    -4
      src/Discord.Net.Commands/Info/ModuleInfo.cs

+ 4
- 4
src/Discord.Net.Commands/Builders/ModuleBuilder.cs View File

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

+ 1
- 1
src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs View File

@@ -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)
{ {


+ 14
- 0
src/Discord.Net.Commands/CommandService.cs View File

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


+ 21
- 0
src/Discord.Net.Commands/IModuleFactory.cs View File

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

+ 4
- 4
src/Discord.Net.Commands/Info/ModuleInfo.cs View File

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


Loading…
Cancel
Save