mirror of
https://github.com/oliverbooth/VpSharp
synced 2024-11-09 23:15:41 +00:00
Add support for dependency injection
This commit is contained in:
parent
55eaa4b510
commit
5b6bbac689
@ -1,4 +1,5 @@
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using VpSharp.ClientExtensions;
|
||||
using VpSharp.Commands.Attributes;
|
||||
using VpSharp.Entities;
|
||||
@ -30,6 +31,7 @@ public sealed class CommandsExtension : VirtualParadiseClientExtension
|
||||
: base(client)
|
||||
{
|
||||
_configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
|
||||
_configuration.Services ??= client.Services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -37,6 +39,7 @@ public sealed class CommandsExtension : VirtualParadiseClientExtension
|
||||
/// </summary>
|
||||
/// <param name="assembly">The assembly whose command modules to register.</param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// A module in the specified assembly does not have a public constructor, or has more than one public constructor.
|
||||
/// </exception>
|
||||
/// <exception cref="TypeInitializationException">A command module could not be instantiated.</exception>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
@ -48,6 +51,10 @@ public sealed class CommandsExtension : VirtualParadiseClientExtension
|
||||
/// A command in the specified assembly has <see cref="RemainderAttribute" /> on a parameter that is not the last in
|
||||
/// the parameter list.
|
||||
/// </para>
|
||||
/// -or-
|
||||
/// <para>
|
||||
/// A module is expecting services but no <see cref="IServiceProvider" /> was registered.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
public void RegisterCommands(Assembly assembly)
|
||||
{
|
||||
@ -66,7 +73,11 @@ public sealed class CommandsExtension : VirtualParadiseClientExtension
|
||||
/// Registers the commands defined in the specified type.
|
||||
/// </summary>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <typeparamref name="T" /> refers to a type that does not inherit <see cref="CommandModule" />.
|
||||
/// <para><typeparamref name="T" /> refers to a type that does not inherit <see cref="CommandModule" />.</para>
|
||||
/// -or-
|
||||
/// <para>
|
||||
/// <typeparamref name="T" /> does not have a public constructor, or has more than one public constructor.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
/// <exception cref="TypeInitializationException"><typeparamref name="T" /> could not be instantiated.</exception>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
@ -78,6 +89,10 @@ public sealed class CommandsExtension : VirtualParadiseClientExtension
|
||||
/// A command in the specified module has <see cref="RemainderAttribute" /> on a parameter that is not the last in the
|
||||
/// parameter list.
|
||||
/// </para>
|
||||
/// -or-
|
||||
/// <para>
|
||||
/// The module is expecting services but no <see cref="IServiceProvider" /> was registered.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
public void RegisterCommands<T>() where T : CommandModule
|
||||
{
|
||||
@ -93,6 +108,10 @@ public sealed class CommandsExtension : VirtualParadiseClientExtension
|
||||
/// <para><paramref name="moduleType" /> refers to an <c>abstract</c> type.</para>
|
||||
/// -or-
|
||||
/// <para><paramref name="moduleType" /> refers to a type that does not inherit <see cref="CommandModule" />.</para>
|
||||
/// -or-
|
||||
/// <para>
|
||||
/// <paramref name="moduleType" /> does not have a public constructor, or has more than one public constructor.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
/// <exception cref="TypeInitializationException"><paramref name="moduleType" /> could not be instantiated.</exception>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
@ -104,6 +123,10 @@ public sealed class CommandsExtension : VirtualParadiseClientExtension
|
||||
/// A command in the specified module has <see cref="RemainderAttribute" /> on a parameter that is not the last in the
|
||||
/// parameter list.
|
||||
/// </para>
|
||||
/// -or-
|
||||
/// <para>
|
||||
/// The module is expecting services but no <see cref="IServiceProvider" /> was registered.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
public void RegisterCommands(Type moduleType)
|
||||
{
|
||||
@ -119,7 +142,29 @@ public sealed class CommandsExtension : VirtualParadiseClientExtension
|
||||
throw new ArgumentException($"Module type is not a subclass of {typeof(CommandModule)}");
|
||||
}
|
||||
|
||||
if (Activator.CreateInstance(moduleType) is not CommandModule module)
|
||||
ConstructorInfo[] constructors = moduleType.GetTypeInfo().DeclaredConstructors.Where(c => c.IsPublic).ToArray();
|
||||
if (constructors.Length != 0)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
$"Constructor for {moduleType} is not public, or {moduleType} has more than one public constructor.");
|
||||
}
|
||||
|
||||
ConstructorInfo constructor = constructors[0];
|
||||
ParameterInfo[] parameters = constructor.GetParameters();
|
||||
|
||||
IServiceProvider? serviceProvider = _configuration.Services;
|
||||
if (parameters.Length != 0 && serviceProvider is null)
|
||||
{
|
||||
throw new InvalidOperationException("No ServiceProvider has been registered!");
|
||||
}
|
||||
|
||||
var args = new object[parameters.Length];
|
||||
for (var index = 0; index < args.Length; index++)
|
||||
{
|
||||
args[index] = serviceProvider!.GetRequiredService(parameters[index].ParameterType);
|
||||
}
|
||||
|
||||
if (Activator.CreateInstance(moduleType, args) is not CommandModule module)
|
||||
{
|
||||
throw new TypeInitializationException(moduleType.FullName, null);
|
||||
}
|
||||
|
@ -5,9 +5,30 @@ namespace VpSharp.Commands;
|
||||
/// </summary>
|
||||
public sealed class CommandsExtensionConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CommandsExtensionConfiguration" /> class.
|
||||
/// </summary>
|
||||
/// <param name="configuration">The configuration to copy.</param>
|
||||
public CommandsExtensionConfiguration(CommandsExtensionConfiguration? configuration = null)
|
||||
{
|
||||
if (configuration is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Prefixes = configuration.Prefixes;
|
||||
Services = configuration.Services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the prefixes to be use for commands.
|
||||
/// </summary>
|
||||
/// <value>The command prefixes, as an array of <see cref="string" /> values.</value>
|
||||
public IReadOnlyList<string> Prefixes { get; set; } = Array.Empty<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the service provider.
|
||||
/// </summary>
|
||||
/// <value>The service provider.</value>
|
||||
public IServiceProvider? Services { get; set; }
|
||||
}
|
||||
|
@ -57,6 +57,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0"/>
|
||||
<PackageReference Include="System.Drawing.Common" Version="7.0.0"/>
|
||||
<PackageReference Include="X10D" Version="3.2.0-nightly.136"/>
|
||||
<PackageReference Include="ZString" Version="2.5.0"/>
|
||||
|
@ -46,6 +46,7 @@ public sealed partial class VirtualParadiseClient : IDisposable
|
||||
/// <value>The configuration for this client.</value>
|
||||
public VirtualParadiseClient(VirtualParadiseConfiguration configuration)
|
||||
{
|
||||
Services = configuration.Services;
|
||||
_configuration = new VirtualParadiseConfiguration(configuration);
|
||||
Initialize();
|
||||
}
|
||||
@ -84,6 +85,12 @@ public sealed partial class VirtualParadiseClient : IDisposable
|
||||
get => CurrentAvatar?.Location.World;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the service provider.
|
||||
/// </summary>
|
||||
/// <value>The service provider.</value>
|
||||
public IServiceProvider? Services { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a read-only view of the cached worlds.
|
||||
/// </summary>
|
||||
|
@ -61,6 +61,12 @@ public sealed class VirtualParadiseConfiguration
|
||||
/// </summary>
|
||||
/// <value>The login password.</value>
|
||||
public string Password { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the service provider.
|
||||
/// </summary>
|
||||
/// <value>The service provider.</value>
|
||||
public IServiceProvider? Services { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the login username.
|
||||
|
Loading…
Reference in New Issue
Block a user