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

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<IModuleBase>(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);
}
}

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


+ 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>
/// Add a command module from a <see cref="Type" />.
/// </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>
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<string> BuildAliases(ModuleBuilder builder, CommandService service)
@@ -106,12 +106,12 @@ namespace Discord.Commands
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>();

foreach (var submodule in parent.Modules)
result.Add(submodule.Build(service, services, this));
result.Add(submodule.Build(service, services, moduleFactory, this));

return result;
}


Loading…
Cancel
Save