mirror of
https://github.com/oliverbooth/VpSharp
synced 2024-11-09 23:35: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 System.Reflection;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using VpSharp.ClientExtensions;
|
using VpSharp.ClientExtensions;
|
||||||
using VpSharp.Commands.Attributes;
|
using VpSharp.Commands.Attributes;
|
||||||
using VpSharp.Entities;
|
using VpSharp.Entities;
|
||||||
@ -30,6 +31,7 @@ public sealed class CommandsExtension : VirtualParadiseClientExtension
|
|||||||
: base(client)
|
: base(client)
|
||||||
{
|
{
|
||||||
_configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
|
_configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
|
||||||
|
_configuration.Services ??= client.Services;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -37,6 +39,7 @@ public sealed class CommandsExtension : VirtualParadiseClientExtension
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="assembly">The assembly whose command modules to register.</param>
|
/// <param name="assembly">The assembly whose command modules to register.</param>
|
||||||
/// <exception cref="ArgumentException">
|
/// <exception cref="ArgumentException">
|
||||||
|
/// A module in the specified assembly does not have a public constructor, or has more than one public constructor.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
/// <exception cref="TypeInitializationException">A command module could not be instantiated.</exception>
|
/// <exception cref="TypeInitializationException">A command module could not be instantiated.</exception>
|
||||||
/// <exception cref="InvalidOperationException">
|
/// <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
|
/// A command in the specified assembly has <see cref="RemainderAttribute" /> on a parameter that is not the last in
|
||||||
/// the parameter list.
|
/// the parameter list.
|
||||||
/// </para>
|
/// </para>
|
||||||
|
/// -or-
|
||||||
|
/// <para>
|
||||||
|
/// A module is expecting services but no <see cref="IServiceProvider" /> was registered.
|
||||||
|
/// </para>
|
||||||
/// </exception>
|
/// </exception>
|
||||||
public void RegisterCommands(Assembly assembly)
|
public void RegisterCommands(Assembly assembly)
|
||||||
{
|
{
|
||||||
@ -66,7 +73,11 @@ public sealed class CommandsExtension : VirtualParadiseClientExtension
|
|||||||
/// Registers the commands defined in the specified type.
|
/// Registers the commands defined in the specified type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <exception cref="ArgumentException">
|
/// <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>
|
||||||
/// <exception cref="TypeInitializationException"><typeparamref name="T" /> could not be instantiated.</exception>
|
/// <exception cref="TypeInitializationException"><typeparamref name="T" /> could not be instantiated.</exception>
|
||||||
/// <exception cref="InvalidOperationException">
|
/// <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
|
/// A command in the specified module has <see cref="RemainderAttribute" /> on a parameter that is not the last in the
|
||||||
/// parameter list.
|
/// parameter list.
|
||||||
/// </para>
|
/// </para>
|
||||||
|
/// -or-
|
||||||
|
/// <para>
|
||||||
|
/// The module is expecting services but no <see cref="IServiceProvider" /> was registered.
|
||||||
|
/// </para>
|
||||||
/// </exception>
|
/// </exception>
|
||||||
public void RegisterCommands<T>() where T : CommandModule
|
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>
|
/// <para><paramref name="moduleType" /> refers to an <c>abstract</c> type.</para>
|
||||||
/// -or-
|
/// -or-
|
||||||
/// <para><paramref name="moduleType" /> refers to a type that does not inherit <see cref="CommandModule" />.</para>
|
/// <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>
|
||||||
/// <exception cref="TypeInitializationException"><paramref name="moduleType" /> could not be instantiated.</exception>
|
/// <exception cref="TypeInitializationException"><paramref name="moduleType" /> could not be instantiated.</exception>
|
||||||
/// <exception cref="InvalidOperationException">
|
/// <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
|
/// A command in the specified module has <see cref="RemainderAttribute" /> on a parameter that is not the last in the
|
||||||
/// parameter list.
|
/// parameter list.
|
||||||
/// </para>
|
/// </para>
|
||||||
|
/// -or-
|
||||||
|
/// <para>
|
||||||
|
/// The module is expecting services but no <see cref="IServiceProvider" /> was registered.
|
||||||
|
/// </para>
|
||||||
/// </exception>
|
/// </exception>
|
||||||
public void RegisterCommands(Type moduleType)
|
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)}");
|
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);
|
throw new TypeInitializationException(moduleType.FullName, null);
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,30 @@ namespace VpSharp.Commands;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class CommandsExtensionConfiguration
|
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>
|
/// <summary>
|
||||||
/// Gets or sets the prefixes to be use for commands.
|
/// Gets or sets the prefixes to be use for commands.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The command prefixes, as an array of <see cref="string" /> values.</value>
|
/// <value>The command prefixes, as an array of <see cref="string" /> values.</value>
|
||||||
public IReadOnlyList<string> Prefixes { get; set; } = Array.Empty<string>();
|
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>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0"/>
|
||||||
<PackageReference Include="System.Drawing.Common" Version="7.0.0"/>
|
<PackageReference Include="System.Drawing.Common" Version="7.0.0"/>
|
||||||
<PackageReference Include="X10D" Version="3.2.0-nightly.136"/>
|
<PackageReference Include="X10D" Version="3.2.0-nightly.136"/>
|
||||||
<PackageReference Include="ZString" Version="2.5.0"/>
|
<PackageReference Include="ZString" Version="2.5.0"/>
|
||||||
|
@ -46,6 +46,7 @@ public sealed partial class VirtualParadiseClient : IDisposable
|
|||||||
/// <value>The configuration for this client.</value>
|
/// <value>The configuration for this client.</value>
|
||||||
public VirtualParadiseClient(VirtualParadiseConfiguration configuration)
|
public VirtualParadiseClient(VirtualParadiseConfiguration configuration)
|
||||||
{
|
{
|
||||||
|
Services = configuration.Services;
|
||||||
_configuration = new VirtualParadiseConfiguration(configuration);
|
_configuration = new VirtualParadiseConfiguration(configuration);
|
||||||
Initialize();
|
Initialize();
|
||||||
}
|
}
|
||||||
@ -84,6 +85,12 @@ public sealed partial class VirtualParadiseClient : IDisposable
|
|||||||
get => CurrentAvatar?.Location.World;
|
get => CurrentAvatar?.Location.World;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the service provider.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The service provider.</value>
|
||||||
|
public IServiceProvider? Services { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a read-only view of the cached worlds.
|
/// Gets a read-only view of the cached worlds.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -61,6 +61,12 @@ public sealed class VirtualParadiseConfiguration
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The login password.</value>
|
/// <value>The login password.</value>
|
||||||
public string Password { get; set; } = string.Empty;
|
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>
|
/// <summary>
|
||||||
/// Gets or sets the login username.
|
/// Gets or sets the login username.
|
||||||
|
Loading…
Reference in New Issue
Block a user