diff --git a/Squidex.sln.DotSettings b/Squidex.sln.DotSettings
index 6c37eafa1..c3b776133 100644
--- a/Squidex.sln.DotSettings
+++ b/Squidex.sln.DotSettings
@@ -2,6 +2,7 @@
False
True
False
+ True
False
True
True
diff --git a/src/Squidex.Infrastructure/Dispatching/ActionContextDispatcher.cs b/src/Squidex.Infrastructure/Dispatching/ActionContextDispatcher.cs
index d859af728..b34477641 100644
--- a/src/Squidex.Infrastructure/Dispatching/ActionContextDispatcher.cs
+++ b/src/Squidex.Infrastructure/Dispatching/ActionContextDispatcher.cs
@@ -1,5 +1,5 @@
// ==========================================================================
-// ActionContextDispatcher.cs
+// FuncDispatcher.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
@@ -7,7 +7,6 @@
// ==========================================================================
using System;
-using System.Collections.Generic;
using System.Linq;
using System.Reflection;
@@ -15,29 +14,57 @@ namespace Squidex.Infrastructure.Dispatching
{
public sealed class ActionContextDispatcher
{
- private static readonly Dictionary> Handlers;
+ public delegate void ActionContextDelegate(TTarget target, T input, TContext context) where T : TIn;
- static ActionContextDispatcher()
+ public static readonly Func On = CreateHandler();
+
+ public static Func CreateHandler(string methodName = "On")
{
- Handlers =
+ Guard.NotNullOrEmpty(methodName, nameof(methodName));
+
+ var handlers =
typeof(TTarget)
- .GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
- .Where(Helper.HasRightName)
- .Where(Helper.HasRightParameters)
- .Select(ActionContextDispatcherFactory.CreateActionHandler)
- .ToDictionary(h => h.Item1, h => h.Item2);
- }
+ .GetMethods(
+ BindingFlags.Public |
+ BindingFlags.NonPublic |
+ BindingFlags.Instance)
+ .Where(m => Helper.HasRightName(m, methodName))
+ .Where(m => Helper.HasRightParameters(m))
+ .Where(m => Helper.HasRightVoidReturn(m))
+ .Select(m =>
+ {
+ var inputType = m.GetParameters()[0].ParameterType;
- public static bool Dispatch(TTarget target, TIn input, TContext context)
- {
- if (!Handlers.TryGetValue(input.GetType(), out Action handler))
+ var factoryMethod =
+ typeof(ActionContextDispatcher)
+ .GetMethod(nameof(Factory),
+ BindingFlags.Static |
+ BindingFlags.NonPublic)
+ .MakeGenericMethod(inputType)
+ .Invoke(null, new object[] { m });
+
+ return (inputType, factoryMethod);
+ })
+ .ToDictionary(m => m.Item1, h => (ActionContextDelegate)h.Item2);
+
+ return (target, input, context) =>
{
+ if (handlers.TryGetValue(input.GetType(), out var handler))
+ {
+ handler(target, input, context);
+
+ return true;
+ }
+
return false;
- }
+ };
+ }
- handler(target, input, context);
+ private static ActionContextDelegate Factory(MethodInfo methodInfo) where T : TIn
+ {
+ var handler = (ActionContextDelegate)methodInfo.CreateDelegate(typeof(ActionContextDelegate));
- return true;
+ return (target, input, context) => handler(target, (T)input, context);
}
}
}
\ No newline at end of file
diff --git a/src/Squidex.Infrastructure/Dispatching/ActionContextDispatcherFactory.cs b/src/Squidex.Infrastructure/Dispatching/ActionContextDispatcherFactory.cs
deleted file mode 100644
index 19f76be73..000000000
--- a/src/Squidex.Infrastructure/Dispatching/ActionContextDispatcherFactory.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-// ==========================================================================
-// ActionContextDispatcherFactory.cs
-// Squidex Headless CMS
-// ==========================================================================
-// Copyright (c) Squidex Group
-// All rights reserved.
-// ==========================================================================
-
-using System;
-using System.Reflection;
-
-// ReSharper disable UnusedMember.Local
-
-namespace Squidex.Infrastructure.Dispatching
-{
- internal static class ActionContextDispatcherFactory
- {
- public static Tuple> CreateActionHandler(MethodInfo methodInfo)
- {
- var inputType = methodInfo.GetParameters()[0].ParameterType;
-
- var factoryMethod =
- typeof(ActionContextDispatcherFactory)
- .GetMethod("Factory", BindingFlags.Static | BindingFlags.NonPublic)
- .MakeGenericMethod(typeof(TTarget), inputType, typeof(TContext));
-
- var handler = factoryMethod.Invoke(null, new object[] { methodInfo });
-
- return new Tuple>(inputType, (Action)handler);
- }
-
- private static Action Factory(MethodInfo methodInfo)
- {
- var type = typeof(Action);
-
- var handler = (Action)methodInfo.CreateDelegate(type);
-
- return (target, input, context) => handler(target, (TIn)input, context);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Squidex.Infrastructure/Dispatching/ActionDispatcher.cs b/src/Squidex.Infrastructure/Dispatching/ActionDispatcher.cs
index 7dbcfae8b..61798cade 100644
--- a/src/Squidex.Infrastructure/Dispatching/ActionDispatcher.cs
+++ b/src/Squidex.Infrastructure/Dispatching/ActionDispatcher.cs
@@ -1,5 +1,5 @@
// ==========================================================================
-// ActionDispatcher.cs
+// FuncDispatcher.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
@@ -7,7 +7,6 @@
// ==========================================================================
using System;
-using System.Collections.Generic;
using System.Linq;
using System.Reflection;
@@ -15,29 +14,57 @@ namespace Squidex.Infrastructure.Dispatching
{
public sealed class ActionDispatcher
{
- private static readonly Dictionary> Handlers;
+ public delegate void ActionDelegate(TTarget target, T input) where T : TIn;
- static ActionDispatcher()
+ public static readonly Func On = CreateHandler();
+
+ public static Func CreateHandler(string methodName = "On")
{
- Handlers =
+ Guard.NotNullOrEmpty(methodName, nameof(methodName));
+
+ var handlers =
typeof(TTarget)
- .GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
- .Where(Helper.HasRightName)
- .Where(Helper.HasRightParameters)
- .Select(ActionDispatcherFactory.CreateActionHandler)
- .ToDictionary(h => h.Item1, h => h.Item2);
- }
+ .GetMethods(
+ BindingFlags.Public |
+ BindingFlags.NonPublic |
+ BindingFlags.Instance)
+ .Where(m => Helper.HasRightName(m, methodName))
+ .Where(m => Helper.HasRightParameters(m))
+ .Where(m => Helper.HasRightVoidReturn(m))
+ .Select(m =>
+ {
+ var inputType = m.GetParameters()[0].ParameterType;
- public static bool Dispatch(TTarget target, TIn item)
- {
- if (!Handlers.TryGetValue(item.GetType(), out Action handler))
+ var factoryMethod =
+ typeof(ActionDispatcher)
+ .GetMethod(nameof(Factory),
+ BindingFlags.Static |
+ BindingFlags.NonPublic)
+ .MakeGenericMethod(inputType)
+ .Invoke(null, new object[] { m });
+
+ return (inputType, factoryMethod);
+ })
+ .ToDictionary(m => m.Item1, h => (ActionDelegate)h.Item2);
+
+ return (target, input) =>
{
+ if (handlers.TryGetValue(input.GetType(), out var handler))
+ {
+ handler(target, input);
+
+ return true;
+ }
+
return false;
- }
+ };
+ }
- handler(target, item);
+ private static ActionDelegate Factory(MethodInfo methodInfo) where T : TIn
+ {
+ var handler = (ActionDelegate)methodInfo.CreateDelegate(typeof(ActionDelegate));
- return true;
+ return (target, input) => handler(target, (T)input);
}
}
}
\ No newline at end of file
diff --git a/src/Squidex.Infrastructure/Dispatching/ActionDispatcherFactory.cs b/src/Squidex.Infrastructure/Dispatching/ActionDispatcherFactory.cs
deleted file mode 100644
index 04de5fe19..000000000
--- a/src/Squidex.Infrastructure/Dispatching/ActionDispatcherFactory.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-// ==========================================================================
-// ActionDispatcherFactory.cs
-// Squidex Headless CMS
-// ==========================================================================
-// Copyright (c) Squidex Group
-// All rights reserved.
-// ==========================================================================
-
-using System;
-using System.Reflection;
-
-// ReSharper disable UnusedMember.Local
-
-namespace Squidex.Infrastructure.Dispatching
-{
- internal static class ActionDispatcherFactory
- {
- public static Tuple> CreateActionHandler(MethodInfo methodInfo)
- {
- var inputType = methodInfo.GetParameters()[0].ParameterType;
-
- var factoryMethod =
- typeof(ActionDispatcherFactory)
- .GetMethod("Factory", BindingFlags.Static | BindingFlags.NonPublic)
- .MakeGenericMethod(typeof(T), inputType);
-
- var handler = factoryMethod.Invoke(null, new object[] { methodInfo });
-
- return new Tuple>(inputType, (Action)handler);
- }
-
- private static Action Factory(MethodInfo methodInfo)
- {
- var type = typeof(Action);
-
- var handler = (Action)methodInfo.CreateDelegate(type);
-
- return (target, input) => handler(target, (TIn)input);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Squidex.Infrastructure/Dispatching/DispatchExtensions.cs b/src/Squidex.Infrastructure/Dispatching/DispatchExtensions.cs
index b482a3273..5d55240ec 100644
--- a/src/Squidex.Infrastructure/Dispatching/DispatchExtensions.cs
+++ b/src/Squidex.Infrastructure/Dispatching/DispatchExtensions.cs
@@ -14,17 +14,17 @@ namespace Squidex.Infrastructure.Dispatching
{
public static bool DispatchAction(this TTarget target, TIn input)
{
- return ActionDispatcher.Dispatch(target, input);
+ return ActionDispatcher.On(target, input);
}
public static bool DispatchAction(this TTarget target, TIn input, TContext context)
{
- return ActionContextDispatcher.Dispatch(target, input, context);
+ return ActionContextDispatcher.On(target, input, context);
}
public static async Task DispatchActionAsync(this TTarget target, TIn input)
{
- var task = FuncDispatcher.Dispatch(target, input);
+ var task = FuncDispatcher.On(target, input);
if (task == null)
{
@@ -38,7 +38,7 @@ namespace Squidex.Infrastructure.Dispatching
public static async Task DispatchActionAsync(this TTarget target, TIn input, TContext context)
{
- var task = FuncContextDispatcher.Dispatch(target, input, context);
+ var task = FuncContextDispatcher.On(target, input, context);
if (task == null)
{
@@ -52,28 +52,28 @@ namespace Squidex.Infrastructure.Dispatching
public static TOut DispatchFunc(this TTarget target, TIn input, TOut fallback)
{
- var result = FuncDispatcher.Dispatch(target, input);
+ var result = FuncDispatcher.On(target, input);
return Equals(result, default(TOut)) ? fallback : result;
}
public static TOut DispatchFunc(this TTarget target, TIn input, TContext context, TOut fallback)
{
- var result = FuncContextDispatcher.Dispatch(target, input, context);
+ var result = FuncContextDispatcher.On(target, input, context);
return Equals(result, default(TOut)) ? fallback : result;
}
public static Task DispatchFuncAsync(this TTarget target, TIn input, TOut fallback)
{
- var result = FuncDispatcher>.Dispatch(target, input);
+ var result = FuncDispatcher>.On(target, input);
return result ?? Task.FromResult(fallback);
}
public static Task DispatchFuncAsync(this TTarget target, TIn input, TContext context, TOut fallback)
{
- var result = FuncContextDispatcher>.Dispatch(target, input, context);
+ var result = FuncContextDispatcher>.On(target, input, context);
return result ?? Task.FromResult(fallback);
}
diff --git a/src/Squidex.Infrastructure/Dispatching/FuncContextDispatcher.cs b/src/Squidex.Infrastructure/Dispatching/FuncContextDispatcher.cs
index 53477114f..576392950 100644
--- a/src/Squidex.Infrastructure/Dispatching/FuncContextDispatcher.cs
+++ b/src/Squidex.Infrastructure/Dispatching/FuncContextDispatcher.cs
@@ -6,8 +6,6 @@
// All rights reserved.
// ==========================================================================
-using System;
-using System.Collections.Generic;
using System.Linq;
using System.Reflection;
@@ -15,23 +13,47 @@ namespace Squidex.Infrastructure.Dispatching
{
public sealed class FuncContextDispatcher
{
- private static readonly Dictionary> Handlers;
+ public delegate TOut FuncContextDelegate(TTarget target, T input, TContext context) where T : TIn;
- static FuncContextDispatcher()
+ public static readonly FuncContextDelegate On = CreateHandler();
+
+ public static FuncContextDelegate CreateHandler(string methodName = "On")
{
- Handlers =
+ Guard.NotNullOrEmpty(methodName, nameof(methodName));
+
+ var handlers =
typeof(TTarget)
- .GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
- .Where(Helper.HasRightName)
- .Where(Helper.HasRightParameters)
- .Where(Helper.HasRightReturnType)
- .Select(FuncContextDispatcherFactory.CreateFuncHandler)
- .ToDictionary(h => h.Item1, h => h.Item2);
+ .GetMethods(
+ BindingFlags.Public |
+ BindingFlags.NonPublic |
+ BindingFlags.Instance)
+ .Where(m => Helper.HasRightName(m, methodName))
+ .Where(m => Helper.HasRightParameters(m))
+ .Where(m => Helper.HasRightReturnType(m))
+ .Select(m =>
+ {
+ var inputType = m.GetParameters()[0].ParameterType;
+
+ var factoryMethod =
+ typeof(FuncContextDispatcher)
+ .GetMethod(nameof(Factory),
+ BindingFlags.Static |
+ BindingFlags.NonPublic)
+ .MakeGenericMethod(inputType)
+ .Invoke(null, new object[] { m });
+
+ return (inputType, factoryMethod);
+ })
+ .ToDictionary(m => m.Item1, h => (FuncContextDelegate)h.Item2);
+
+ return (target, input, context) => handlers.TryGetValue(input.GetType(), out var handler) ? handler(target, input, context) : default(TOut);
}
- public static TOut Dispatch(TTarget target, TIn item, TContext context)
+ private static FuncContextDelegate Factory(MethodInfo methodInfo) where T : TIn
{
- return Handlers.TryGetValue(item.GetType(), out Func handler) ? handler(target, item, context) : default(TOut);
+ var handler = (FuncContextDelegate)methodInfo.CreateDelegate(typeof(FuncContextDelegate));
+
+ return (target, input, context) => handler(target, (T)input, context);
}
}
}
\ No newline at end of file
diff --git a/src/Squidex.Infrastructure/Dispatching/FuncContextDispatcherFactory.cs b/src/Squidex.Infrastructure/Dispatching/FuncContextDispatcherFactory.cs
deleted file mode 100644
index faaca2ecf..000000000
--- a/src/Squidex.Infrastructure/Dispatching/FuncContextDispatcherFactory.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-// ==========================================================================
-// FuncContextDispatcherFactory.cs
-// Squidex Headless CMS
-// ==========================================================================
-// Copyright (c) Squidex Group
-// All rights reserved.
-// ==========================================================================
-
-using System;
-using System.Reflection;
-
-// ReSharper disable UnusedMember.Local
-
-namespace Squidex.Infrastructure.Dispatching
-{
- internal static class FuncContextDispatcherFactory
- {
- public static Tuple> CreateFuncHandler(MethodInfo methodInfo)
- {
- var inputType = methodInfo.GetParameters()[0].ParameterType;
-
- var factoryMethod =
- typeof(FuncContextDispatcherFactory)
- .GetMethod("Factory", BindingFlags.Static | BindingFlags.NonPublic)
- .MakeGenericMethod(typeof(TTarget), inputType, typeof(TContext), methodInfo.ReturnType);
-
- var handler = factoryMethod.Invoke(null, new object[] { methodInfo });
-
- return new Tuple>(inputType, (Func)handler);
- }
-
- private static Func Factory(MethodInfo methodInfo)
- {
- var type = typeof(Func);
-
- var handler = (Func)methodInfo.CreateDelegate(type);
-
- return (target, input, context) => handler(target, (TIn)input, context);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Squidex.Infrastructure/Dispatching/FuncDispatcher.cs b/src/Squidex.Infrastructure/Dispatching/FuncDispatcher.cs
index ce18f9085..ee607b37b 100644
--- a/src/Squidex.Infrastructure/Dispatching/FuncDispatcher.cs
+++ b/src/Squidex.Infrastructure/Dispatching/FuncDispatcher.cs
@@ -6,8 +6,6 @@
// All rights reserved.
// ==========================================================================
-using System;
-using System.Collections.Generic;
using System.Linq;
using System.Reflection;
@@ -15,23 +13,47 @@ namespace Squidex.Infrastructure.Dispatching
{
public sealed class FuncDispatcher
{
- private static readonly Dictionary> Handlers;
+ public delegate TOut FuncDelegate(TTarget target, T input) where T : TIn;
- static FuncDispatcher()
+ public static readonly FuncDelegate On = CreateHandler();
+
+ public static FuncDelegate CreateHandler(string methodName = "On")
{
- Handlers =
+ Guard.NotNullOrEmpty(methodName, nameof(methodName));
+
+ var handlers =
typeof(TTarget)
- .GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
- .Where(Helper.HasRightName)
- .Where(Helper.HasRightParameters)
- .Where(Helper.HasRightReturnType)
- .Select(FuncDispatcherFactory.CreateFuncHandler)
- .ToDictionary(h => h.Item1, h => h.Item2);
+ .GetMethods(
+ BindingFlags.Public |
+ BindingFlags.NonPublic |
+ BindingFlags.Instance)
+ .Where(m => Helper.HasRightName(m, methodName))
+ .Where(m => Helper.HasRightParameters(m))
+ .Where(m => Helper.HasRightReturnType(m))
+ .Select(m =>
+ {
+ var inputType = m.GetParameters()[0].ParameterType;
+
+ var factoryMethod =
+ typeof(FuncDispatcher)
+ .GetMethod(nameof(Factory),
+ BindingFlags.Static |
+ BindingFlags.NonPublic)
+ .MakeGenericMethod(inputType)
+ .Invoke(null, new object[] { m });
+
+ return (inputType, factoryMethod);
+ })
+ .ToDictionary(m => m.Item1, h => (FuncDelegate)h.Item2);
+
+ return (target, input) => handlers.TryGetValue(input.GetType(), out var handler) ? handler(target, input) : default(TOut);
}
- public static TOut Dispatch(TTarget target, TIn item)
+ private static FuncDelegate Factory(MethodInfo methodInfo) where T : TIn
{
- return Handlers.TryGetValue(item.GetType(), out Func handler) ? handler(target, item) : default(TOut);
+ var handler = (FuncDelegate)methodInfo.CreateDelegate(typeof(FuncDelegate));
+
+ return (target, input) => handler(target, (T)input);
}
}
}
\ No newline at end of file
diff --git a/src/Squidex.Infrastructure/Dispatching/FuncDispatcherFactory.cs b/src/Squidex.Infrastructure/Dispatching/FuncDispatcherFactory.cs
deleted file mode 100644
index d57927727..000000000
--- a/src/Squidex.Infrastructure/Dispatching/FuncDispatcherFactory.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-// ==========================================================================
-// FuncDispatcherFactory.cs
-// Squidex Headless CMS
-// ==========================================================================
-// Copyright (c) Squidex Group
-// All rights reserved.
-// ==========================================================================
-
-using System;
-using System.Reflection;
-
-// ReSharper disable once UnusedMember.Local
-
-namespace Squidex.Infrastructure.Dispatching
-{
- internal static class FuncDispatcherFactory
- {
- public static Tuple> CreateFuncHandler(MethodInfo methodInfo)
- {
- var inputType = methodInfo.GetParameters()[0].ParameterType;
-
- var factoryMethod =
- typeof(FuncDispatcherFactory)
- .GetMethod("Factory", BindingFlags.Static | BindingFlags.NonPublic)
- .MakeGenericMethod(typeof(TTarget), inputType, methodInfo.ReturnType);
-
- var handler = factoryMethod.Invoke(null, new object[] { methodInfo });
-
- return new Tuple>(inputType, (Func)handler);
- }
-
- private static Func Factory(MethodInfo methodInfo)
- {
- var type = typeof(Func);
-
- var handler = (Func)methodInfo.CreateDelegate(type);
-
- return (target, input) => handler(target, (TIn)input);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Squidex.Infrastructure/Dispatching/Helper.cs b/src/Squidex.Infrastructure/Dispatching/Helper.cs
index 3cffea5a2..ebf87b328 100644
--- a/src/Squidex.Infrastructure/Dispatching/Helper.cs
+++ b/src/Squidex.Infrastructure/Dispatching/Helper.cs
@@ -13,6 +13,11 @@ namespace Squidex.Infrastructure.Dispatching
{
internal static class Helper
{
+ public static bool HasRightName(MethodInfo method, string name)
+ {
+ return string.Equals(method.Name, name, StringComparison.OrdinalIgnoreCase);
+ }
+
public static bool HasRightName(MethodInfo method)
{
return string.Equals(method.Name, "On", StringComparison.OrdinalIgnoreCase);
@@ -23,6 +28,11 @@ namespace Squidex.Infrastructure.Dispatching
return method.ReturnType == typeof(TOut);
}
+ public static bool HasRightVoidReturn(MethodInfo method)
+ {
+ return method.ReturnType == typeof(void);
+ }
+
public static bool HasRightParameters(MethodInfo method)
{
var parameters = method.GetParameters();