Add Dependency Map, Update Assembly Crawler
[Untested] Assembly Crawler will now accept constructors matching: new(), new(CommandService), new(IDependencyMap). Add IDependencyMap Add DependencyMap
This commit is contained in:
@@ -164,7 +164,7 @@ namespace Discord.Commands
|
|||||||
|
|
||||||
return loadedModule;
|
return loadedModule;
|
||||||
}
|
}
|
||||||
public async Task<IEnumerable<Module>> LoadAssembly(Assembly assembly)
|
public async Task<IEnumerable<Module>> LoadAssembly(Assembly assembly, IDependencyMap dependencyMap = null)
|
||||||
{
|
{
|
||||||
var modules = ImmutableArray.CreateBuilder<Module>();
|
var modules = ImmutableArray.CreateBuilder<Module>();
|
||||||
await _moduleLock.WaitAsync().ConfigureAwait(false);
|
await _moduleLock.WaitAsync().ConfigureAwait(false);
|
||||||
@@ -176,7 +176,7 @@ namespace Discord.Commands
|
|||||||
var moduleAttr = typeInfo.GetCustomAttribute<ModuleAttribute>();
|
var moduleAttr = typeInfo.GetCustomAttribute<ModuleAttribute>();
|
||||||
if (moduleAttr != null && moduleAttr.Autoload)
|
if (moduleAttr != null && moduleAttr.Autoload)
|
||||||
{
|
{
|
||||||
var moduleInstance = ReflectionUtils.CreateObject(typeInfo);
|
var moduleInstance = ReflectionUtils.CreateObject(typeInfo, this, dependencyMap);
|
||||||
modules.Add(LoadInternal(moduleInstance, moduleAttr, typeInfo));
|
modules.Add(LoadInternal(moduleInstance, moduleAttr, typeInfo));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
27
src/Discord.Net.Commands/Dependencies/DependencyMap.cs
Normal file
27
src/Discord.Net.Commands/Dependencies/DependencyMap.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace Discord.Commands
|
||||||
|
{
|
||||||
|
public class DependencyMap : IDependencyMap
|
||||||
|
{
|
||||||
|
private Dictionary<Type, object> map;
|
||||||
|
|
||||||
|
public T Get<T>() where T : class
|
||||||
|
{
|
||||||
|
var t = typeof(T);
|
||||||
|
if (!map.ContainsKey(t))
|
||||||
|
throw new KeyNotFoundException($"The dependency map does not contain \"{t.FullName}\"");
|
||||||
|
return map[t] as T;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Add<T>(T obj)
|
||||||
|
{
|
||||||
|
var t = typeof(T);
|
||||||
|
if (map.ContainsKey(t))
|
||||||
|
throw new InvalidOperationException($"The dependency map already contains \"{t.FullName}\"");
|
||||||
|
map.Add(t, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
13
src/Discord.Net.Commands/Dependencies/IDependencyMap.cs
Normal file
13
src/Discord.Net.Commands/Dependencies/IDependencyMap.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Discord.Commands
|
||||||
|
{
|
||||||
|
public interface IDependencyMap
|
||||||
|
{
|
||||||
|
T Get<T>() where T : class;
|
||||||
|
void Add<T>(T obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,7 +43,7 @@ namespace Discord.Commands
|
|||||||
nextGroupPrefix = groupPrefix + groupAttrib.Prefix ?? type.Name;
|
nextGroupPrefix = groupPrefix + groupAttrib.Prefix ?? type.Name;
|
||||||
else
|
else
|
||||||
nextGroupPrefix = groupPrefix;
|
nextGroupPrefix = groupPrefix;
|
||||||
SearchClass(ReflectionUtils.CreateObject(type), commands, type, nextGroupPrefix);
|
SearchClass(ReflectionUtils.CreateObject(type, Service), commands, type, nextGroupPrefix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,18 +6,33 @@ namespace Discord.Commands
|
|||||||
{
|
{
|
||||||
internal class ReflectionUtils
|
internal class ReflectionUtils
|
||||||
{
|
{
|
||||||
internal static object CreateObject(TypeInfo typeInfo)
|
internal static object CreateObject(TypeInfo typeInfo, CommandService commands, IDependencyMap map = null)
|
||||||
{
|
{
|
||||||
var constructor = typeInfo.DeclaredConstructors.Where(x => x.GetParameters().Length == 0).FirstOrDefault();
|
if (typeInfo.DeclaredConstructors.Count() > 1)
|
||||||
if (constructor == null)
|
throw new InvalidOperationException($"Found too many constructors for \"{typeInfo.FullName}\"");
|
||||||
throw new InvalidOperationException($"Failed to find a valid constructor for \"{typeInfo.FullName}\"");
|
var constructor = typeInfo.DeclaredConstructors.FirstOrDefault();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return constructor.Invoke(null);
|
if (constructor.GetParameters().Length == 0)
|
||||||
|
return constructor.Invoke(null);
|
||||||
|
else if (constructor.GetParameters().Length > 1)
|
||||||
|
throw new InvalidOperationException($"Could not find a valid constructor for \"{typeInfo.FullName}\"");
|
||||||
|
var parameter = constructor.GetParameters().FirstOrDefault();
|
||||||
|
if (parameter == null)
|
||||||
|
throw new InvalidOperationException($"Could not find a valid constructor for \"{typeInfo.FullName}\"");
|
||||||
|
if (parameter.GetType() == typeof(CommandService))
|
||||||
|
return constructor.Invoke(new object[1] { commands });
|
||||||
|
else if (parameter is IDependencyMap)
|
||||||
|
{
|
||||||
|
if (map == null) throw new InvalidOperationException($"The constructor for \"{typeInfo.FullName}\" requires a Dependency Map.");
|
||||||
|
return constructor.Invoke(new object[1] { map });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new InvalidOperationException($"Could not find a valid constructor for \"{typeInfo.FullName}\"");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Failed to create \"{typeInfo.FullName}\"", ex);
|
throw new InvalidOperationException($"Could not find a valid constructor for \"{typeInfo.FullName}\"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user