Browse Source

Add Dependency Map, Update Assembly Crawler

[Untested] Assembly Crawler will now accept constructors matching: new(), new(CommandService), new(IDependencyMap).

Add IDependencyMap

Add DependencyMap
tags/1.0-rc
Christopher F 9 years ago
parent
commit
bbe51012cf
5 changed files with 65 additions and 10 deletions
  1. +2
    -2
      src/Discord.Net.Commands/CommandService.cs
  2. +27
    -0
      src/Discord.Net.Commands/Dependencies/DependencyMap.cs
  3. +13
    -0
      src/Discord.Net.Commands/Dependencies/IDependencyMap.cs
  4. +1
    -1
      src/Discord.Net.Commands/Module.cs
  5. +22
    -7
      src/Discord.Net.Commands/ReflectionUtils.cs

+ 2
- 2
src/Discord.Net.Commands/CommandService.cs View File

@@ -164,7 +164,7 @@ namespace Discord.Commands

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>();
await _moduleLock.WaitAsync().ConfigureAwait(false);
@@ -176,7 +176,7 @@ namespace Discord.Commands
var moduleAttr = typeInfo.GetCustomAttribute<ModuleAttribute>();
if (moduleAttr != null && moduleAttr.Autoload)
{
var moduleInstance = ReflectionUtils.CreateObject(typeInfo);
var moduleInstance = ReflectionUtils.CreateObject(typeInfo, this, dependencyMap);
modules.Add(LoadInternal(moduleInstance, moduleAttr, typeInfo));
}
}


+ 27
- 0
src/Discord.Net.Commands/Dependencies/DependencyMap.cs View 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
- 0
src/Discord.Net.Commands/Dependencies/IDependencyMap.cs View 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);
}
}

+ 1
- 1
src/Discord.Net.Commands/Module.cs View File

@@ -43,7 +43,7 @@ namespace Discord.Commands
nextGroupPrefix = groupPrefix + groupAttrib.Prefix ?? type.Name;
else
nextGroupPrefix = groupPrefix;
SearchClass(ReflectionUtils.CreateObject(type), commands, type, nextGroupPrefix);
SearchClass(ReflectionUtils.CreateObject(type, Service), commands, type, nextGroupPrefix);
}
}
}


+ 22
- 7
src/Discord.Net.Commands/ReflectionUtils.cs View File

@@ -6,18 +6,33 @@ namespace Discord.Commands
{
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 (constructor == null)
throw new InvalidOperationException($"Failed to find a valid constructor for \"{typeInfo.FullName}\"");
if (typeInfo.DeclaredConstructors.Count() > 1)
throw new InvalidOperationException($"Found too many constructors for \"{typeInfo.FullName}\"");
var constructor = typeInfo.DeclaredConstructors.FirstOrDefault();
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}\"");
}
}
}


Loading…
Cancel
Save