This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
gameservicewarden/GameServiceWarden/GameServiceWarden.Core/Module/ModuleLoader.cs

74 lines
2.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Reflection;
using GameServiceWarden.Core.Module.Exceptions;
using GameServiceWarden.ModuleFramework;
namespace GameServiceWarden.Core.Module
{
public class ModuleLoader //Gateway
{
/// <summary>
/// Loads an extension module.
/// </summary>
/// <param name="path">The path to the module.</param>
/// <returns>An </<see cref="IEnumerable{IServiceModule}"/> from the given module.</returns>
/// <exception cref="NoServiceableFoundException">When the module requested to be loaded does not contain any public <see cref="IService"/> classes.</exception>
public IEnumerable<IServiceModule> LoadModules(string path)
{
return instantiateServiceable(loadAssembly(path));
}
/// <summary>
/// Loads all module for each given path to modules file.
/// </summary>
/// <param name="paths">The paths to load modules for.</param>
/// <returns>A <see cref="Dictionary{string, IEnumerable{IServiceModule}}"/> where the key is a <see cref="string"/> that is the associated path.</returns>
public Dictionary<string, IEnumerable<IServiceModule>> LoadAllModules(IEnumerable<string> paths)
{
Dictionary<string, IEnumerable<IServiceModule>> res = new Dictionary<string, IEnumerable<IServiceModule>>();
foreach (string path in paths)
{
res.Add(path, LoadModules(path));
}
return res;
}
private Assembly loadAssembly(string path)
{
ModuleLoadContext moduleLoadContext = new ModuleLoadContext(path);
return moduleLoadContext.LoadFromAssemblyPath(path);
}
private IEnumerable<IServiceModule> instantiateServiceable(Assembly assembly)
{
int serviceableCount = 0;
foreach (Type type in assembly.GetExportedTypes())
{
if (typeof(IServiceModule).IsAssignableFrom(type))
{
IServiceModule res = Activator.CreateInstance(type) as IServiceModule;
if (res != null)
{
serviceableCount++;
yield return res;
}
}
}
if (serviceableCount == 0)
{
List<string> typeNames = new List<string>();
foreach (Type type in assembly.GetExportedTypes())
{
typeNames.Add(type.FullName);
}
string types = String.Join(',', typeNames);
throw new ModuleLoadException(
$"No public classes in {assembly} from {assembly.Location} implemented {typeof(IService).FullName}." +
$"Detected types: {types}");
}
}
}
}