|
@@ -1,42 +1,158 @@
|
|
|
-using System;
|
|
|
+using InABox.Configuration;
|
|
|
+using InABox.Core.Postable;
|
|
|
+using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Linq;
|
|
|
+using System.Reflection;
|
|
|
+using System.Runtime;
|
|
|
using System.Text;
|
|
|
|
|
|
namespace InABox.Core
|
|
|
{
|
|
|
+ namespace Postable
|
|
|
+ {
|
|
|
+ public class MissingSettingsException : Exception
|
|
|
+ {
|
|
|
+ public Type PostableType { get; }
|
|
|
+
|
|
|
+ public MissingSettingsException(Type postableType) : base($"No PostableSettings for ${postableType}")
|
|
|
+ {
|
|
|
+ PostableType = postableType;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
public static class PosterUtils
|
|
|
{
|
|
|
- private static Dictionary<Type, Type>? _posterEngines;
|
|
|
+ private class EngineType
|
|
|
+ {
|
|
|
+ public Type Engine { get; set; }
|
|
|
+
|
|
|
+ public Type Poster { get; set; }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static EngineType[]? _posterEngines;
|
|
|
+ private static Type[]? _posters = null;
|
|
|
+
|
|
|
+ public static Type[] GetPosters()
|
|
|
+ {
|
|
|
+ _posters ??= CoreUtils.TypeList(
|
|
|
+ AppDomain.CurrentDomain.GetAssemblies(),
|
|
|
+ x => x.IsClass
|
|
|
+ && !x.IsAbstract
|
|
|
+ && !x.IsGenericType
|
|
|
+ && x.HasInterface(typeof(IPoster<,>))).ToArray();
|
|
|
+ return _posters;
|
|
|
+ }
|
|
|
|
|
|
- private static Dictionary<Type, Type> GetPosterEngines()
|
|
|
+ private static EngineType[] GetPosterEngines()
|
|
|
{
|
|
|
_posterEngines ??= CoreUtils.TypeList(
|
|
|
AppDomain.CurrentDomain.GetAssemblies(),
|
|
|
x => x.IsClass
|
|
|
&& !x.IsAbstract
|
|
|
- && x.GenericTypeArguments.Length == 1
|
|
|
- && x.HasInterface(typeof(IPosterEngine<>))
|
|
|
- ).ToDictionary(
|
|
|
- x => x.GetInterfaceDefinition(typeof(IPosterEngine<>))!.GenericTypeArguments[0],
|
|
|
- x => x);
|
|
|
+ && x.GetTypeInfo().GenericTypeParameters.Length == 1
|
|
|
+ && x.HasInterface(typeof(IPosterEngine<,,>))
|
|
|
+ ).Select(x => new EngineType
|
|
|
+ {
|
|
|
+ Engine = x,
|
|
|
+ Poster = x.GetInterfaceDefinition(typeof(IPosterEngine<,,>))!.GenericTypeArguments[1].GetGenericTypeDefinition()
|
|
|
+ }).ToArray();
|
|
|
return _posterEngines;
|
|
|
}
|
|
|
|
|
|
- public static Type GetEngine<T>()
|
|
|
+ private static PostableSettings FixPostableSettings<TPostable>(PostableSettings settings)
|
|
|
+ where TPostable : Entity, IPostable
|
|
|
+ {
|
|
|
+ if (string.IsNullOrWhiteSpace(settings.PostableType))
|
|
|
+ {
|
|
|
+ settings.PostableType = typeof(TPostable).EntityName();
|
|
|
+ }
|
|
|
+ return settings;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static PostableSettings LoadPostableSettings<T>()
|
|
|
where T : Entity, IPostable
|
|
|
{
|
|
|
- return GetPosterEngines().GetValueOrDefault(typeof(T))
|
|
|
- ?? throw new Exception($"No poster engine for type {typeof(T).Name}");
|
|
|
+ return FixPostableSettings<T>(new GlobalConfiguration<PostableSettings>(typeof(T).Name).Load());
|
|
|
}
|
|
|
- public static IPosterEngine<T> CreateEngine<T>()
|
|
|
+
|
|
|
+ public static void SavePostableSettings<T>(PostableSettings settings)
|
|
|
where T : Entity, IPostable
|
|
|
+ {
|
|
|
+ new GlobalConfiguration<PostableSettings>(typeof(T).Name).Save(FixPostableSettings<T>(settings));
|
|
|
+ }
|
|
|
+
|
|
|
+ private static TSettings FixPosterSettings<TPostable, TSettings>(TSettings settings)
|
|
|
+ where TPostable : IPostable
|
|
|
+ where TSettings : PosterSettings, new()
|
|
|
+ {
|
|
|
+ if (string.IsNullOrWhiteSpace(settings.PostableType))
|
|
|
+ {
|
|
|
+ settings.PostableType = typeof(TPostable).EntityName();
|
|
|
+ }
|
|
|
+ return settings;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static MethodInfo _loadPosterSettingsMethod = typeof(PosterUtils).GetMethods(BindingFlags.Static | BindingFlags.Public)
|
|
|
+ .Where(x => x.Name == nameof(LoadPosterSettings) && x.IsGenericMethod)
|
|
|
+ .Single();
|
|
|
+ private static MethodInfo _savePosterSettingsMethod = typeof(PosterUtils).GetMethods(BindingFlags.Static | BindingFlags.Public)
|
|
|
+ .Where(x => x.Name == nameof(SavePosterSettings) && x.IsGenericMethod)
|
|
|
+ .Single();
|
|
|
+
|
|
|
+ public static TSettings LoadPosterSettings<TPostable, TSettings>()
|
|
|
+ where TPostable : IPostable
|
|
|
+ where TSettings : PosterSettings, new()
|
|
|
+ {
|
|
|
+ return FixPosterSettings<TPostable, TSettings>(new GlobalConfiguration<TSettings>(typeof(TPostable).Name).Load());
|
|
|
+ }
|
|
|
+
|
|
|
+ public static PosterSettings LoadPosterSettings(Type TPostable, Type TSettings)
|
|
|
+ {
|
|
|
+ return (_loadPosterSettingsMethod.MakeGenericMethod(TPostable, TSettings).Invoke(null, Array.Empty<object>()) as PosterSettings)!;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void SavePosterSettings<TPostable, TSettings>(TSettings settings)
|
|
|
+ where TPostable : IPostable
|
|
|
+ where TSettings : PosterSettings, new()
|
|
|
+ {
|
|
|
+ new GlobalConfiguration<TSettings>(typeof(TPostable).Name).Save(FixPosterSettings<TPostable, TSettings>(settings));
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void SavePosterSettings(Type TPostable, Type TSettings, PosterSettings settings)
|
|
|
+ {
|
|
|
+ _savePosterSettingsMethod.MakeGenericMethod(TPostable, TSettings).Invoke(null, new object[] { settings });
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Get the <see cref="IPosterEngine{TPostable,TPoster,TSettings}"/> for <typeparamref name="T"/>
|
|
|
+ /// based on the current <see cref="PostableSettings"/> for <typeparamref name="T"/>.
|
|
|
+ /// </summary>
|
|
|
+ /// <typeparam name="T"></typeparam>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static Type GetEngine<T>()
|
|
|
+ where T : Entity, IPostable, IRemotable, IPersistent, new()
|
|
|
+ {
|
|
|
+ var settings = LoadPostableSettings<T>();
|
|
|
+ if (string.IsNullOrWhiteSpace(settings.PosterType))
|
|
|
+ {
|
|
|
+ throw new MissingSettingsException(typeof(T));
|
|
|
+ }
|
|
|
+ var poster = GetPosters()?.FirstOrDefault(x => x.EntityName() == settings.PosterType)!;
|
|
|
+
|
|
|
+ return (GetPosterEngines().FirstOrDefault(x => poster.HasInterface(x.Poster))?.Engine
|
|
|
+ ?? throw new Exception("No poster for the given settings.")).MakeGenericType(typeof(T));
|
|
|
+ }
|
|
|
+
|
|
|
+ public static IPosterEngine<T> CreateEngine<T>()
|
|
|
+ where T : Entity, IPostable, IRemotable, IPersistent, new()
|
|
|
{
|
|
|
return (Activator.CreateInstance(GetEngine<T>()) as IPosterEngine<T>)!;
|
|
|
}
|
|
|
|
|
|
public static bool Process<T>(IEnumerable<T> entities)
|
|
|
- where T : Entity, IPostable
|
|
|
+ where T : Entity, IPostable, IRemotable, IPersistent, new()
|
|
|
{
|
|
|
return CreateEngine<T>().Process(entities);
|
|
|
}
|