Move instance creation to VpSharp base

Introduces internal DepdencyInjectionUtility class
This commit is contained in:
Oliver Booth 2022-12-10 13:40:47 +00:00
parent 18f26925da
commit 2fc22fa8a6
No known key found for this signature in database
GPG Key ID: 32A00B35503AF634
3 changed files with 76 additions and 23 deletions

View File

@ -5,6 +5,7 @@ using VpSharp.Commands.Attributes;
using VpSharp.Commands.Attributes.ExecutionChecks;
using VpSharp.Entities;
using VpSharp.EventData;
using VpSharp.Internal;
namespace VpSharp.Commands;
@ -146,29 +147,9 @@ public sealed class CommandsExtension : VirtualParadiseClientExtension
throw new ArgumentException($"Module type is not a subclass of {typeof(CommandModule)}");
}
ConstructorInfo[] constructors = moduleType.GetTypeInfo().DeclaredConstructors.Where(c => c.IsPublic).ToArray();
if (constructors.Length != 1)
{
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)
object instance = DependencyInjectionUtility.CreateInstance(moduleType, serviceProvider);
if (instance is not CommandModule module)
{
throw new TypeInitializationException(moduleType.FullName, null);
}
@ -180,7 +161,7 @@ public sealed class CommandsExtension : VirtualParadiseClientExtension
}
/// <inheritdoc />
protected override Task OnMessageReceived(MessageReceivedEventArgs args)
protected internal override Task OnMessageReceived(MessageReceivedEventArgs args)
{
ArgumentNullException.ThrowIfNull(args);
VirtualParadiseMessage message = args.Message;

View File

@ -1,5 +1,6 @@
using System.Runtime.CompilerServices;
[assembly: CLSCompliant(true)]
[assembly: InternalsVisibleTo("VpSharp.Commands")]
[assembly: InternalsVisibleTo("VpSharp.IntegrationTests")]
[assembly: InternalsVisibleTo("VpSharp.Tests")]

View File

@ -0,0 +1,71 @@
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
namespace VpSharp.Internal;
internal static class DependencyInjectionUtility
{
public static T CreateInstance<T>(VirtualParadiseClient client)
{
return CreateInstance<T>(client.Services);
}
public static T CreateInstance<T>(IServiceProvider? serviceProvider = null)
{
return (T)CreateInstance(typeof(T), serviceProvider);
}
public static object CreateInstance(Type type, VirtualParadiseClient client)
{
ArgumentNullException.ThrowIfNull(type);
ArgumentNullException.ThrowIfNull(client);
return CreateInstance(type, client.Services);
}
public static object CreateInstance(Type type, IServiceProvider? serviceProvider = null)
{
ArgumentNullException.ThrowIfNull(type);
object? instance;
TypeInfo typeInfo = type.GetTypeInfo();
ConstructorInfo[] constructors = typeInfo.DeclaredConstructors.Where(c => c.IsPublic).ToArray();
if (constructors.Length != 1)
{
throw new InvalidOperationException($"{type} has no public constructors, or has more than one public constructor.");
}
ConstructorInfo constructor = constructors[0];
ParameterInfo[] parameters = constructor.GetParameters();
if (parameters.Length > 0 && serviceProvider is null)
{
throw new InvalidOperationException("No ServiceProvider has been registered!");
}
if (parameters.Length == 0)
{
instance = Activator.CreateInstance(type);
if (instance is null)
{
throw new TypeInitializationException(type.FullName, null);
}
return instance;
}
var args = new object[parameters.Length];
for (var index = 0; index < parameters.Length; index++)
{
args[index] = serviceProvider!.GetRequiredService(parameters[index].ParameterType);
}
instance = Activator.CreateInstance(type, args);
if (instance is null)
{
throw new TypeInitializationException(type.FullName, null);
}
return instance;
}
}