From 02a6c3bf6ae1e1a22ff0ba6a88a5ff46084b8476 Mon Sep 17 00:00:00 2001 From: Pilzinsel64 Date: Wed, 14 Aug 2024 14:59:05 +0200 Subject: [PATCH] begin developing a basic message based web api --- Pilz.Networking/Api/ApiClient.cs | 9 ++++ Pilz.Networking/Api/ApiMessage.cs | 14 ++++++ Pilz.Networking/Api/ApiServer.cs | 49 +++++++++++++++++++ .../Api/DefaultMessageSerializer.cs | 14 ++++++ Pilz.Networking/Api/IApiClient.cs | 6 +++ Pilz.Networking/Api/IApiServer.cs | 7 +++ Pilz.Networking/Api/IMessageSerializer.cs | 7 +++ .../Api/MessageHandlerAttribute.cs | 8 +++ Pilz.Networking/Pilz.Networking.csproj | 1 + 9 files changed, 115 insertions(+) create mode 100644 Pilz.Networking/Api/ApiClient.cs create mode 100644 Pilz.Networking/Api/ApiMessage.cs create mode 100644 Pilz.Networking/Api/ApiServer.cs create mode 100644 Pilz.Networking/Api/DefaultMessageSerializer.cs create mode 100644 Pilz.Networking/Api/IApiClient.cs create mode 100644 Pilz.Networking/Api/IApiServer.cs create mode 100644 Pilz.Networking/Api/IMessageSerializer.cs create mode 100644 Pilz.Networking/Api/MessageHandlerAttribute.cs diff --git a/Pilz.Networking/Api/ApiClient.cs b/Pilz.Networking/Api/ApiClient.cs new file mode 100644 index 0000000..392a95e --- /dev/null +++ b/Pilz.Networking/Api/ApiClient.cs @@ -0,0 +1,9 @@ +namespace Pilz.Networking.Api; + +public class ApiClient : IApiClient +{ + public void MakeRequest(string url, T message) where T : ApiMessage + { + // ... + } +} diff --git a/Pilz.Networking/Api/ApiMessage.cs b/Pilz.Networking/Api/ApiMessage.cs new file mode 100644 index 0000000..a1ba7d1 --- /dev/null +++ b/Pilz.Networking/Api/ApiMessage.cs @@ -0,0 +1,14 @@ +namespace Pilz.Networking.Api; + +public abstract class ApiMessage +{ + internal protected virtual string? Serialize(ApiMessage message) + { + + } + + internal protected virtual ApiMessage? Deserialize(string json) + { + + } +} diff --git a/Pilz.Networking/Api/ApiServer.cs b/Pilz.Networking/Api/ApiServer.cs new file mode 100644 index 0000000..4b65db1 --- /dev/null +++ b/Pilz.Networking/Api/ApiServer.cs @@ -0,0 +1,49 @@ +using System.Reflection; + +namespace Pilz.Networking.Api; + +public class ApiServer : ApiClient, IApiServer +{ + protected readonly Dictionary handlers = []; + protected readonly Dictionary serializers = []; + + public IMessageSerializer Serializer { get; set; } = new DefaultMessageSerializer(); + + public virtual void RegisterHandler(string url, T instance) where T : class + { + var methods = typeof(T).GetMethods(BindingFlags.Instance | BindingFlags.Public); + + foreach (var method in methods) + { + if (method.GetCustomAttribute() is not MessageHandlerAttribute attribute + || method.GetParameters().FirstOrDefault() is not ParameterInfo parameterInfo + || !parameterInfo.ParameterType.IsAssignableTo(typeof(ApiMessage))) + continue; + + + var serializer = Serializer; + if (attribute.Serializer is not null) + { + if (serializers.TryGetValue(attribute.Serializer, out var s) && s is not null) + serializer = s; + else if (Activator.CreateInstance(attribute.Serializer) is IMessageSerializer ss) + { + serializer = ss; + serializers.Add(attribute.Serializer, ss); + } + } + + // ... + } + } + + public virtual void RegisterHandler(string url, Delegate handler) + { + // ... + } + + protected virtual string? HandleMessage(string url, string json) + { + // ... + } +} diff --git a/Pilz.Networking/Api/DefaultMessageSerializer.cs b/Pilz.Networking/Api/DefaultMessageSerializer.cs new file mode 100644 index 0000000..df98251 --- /dev/null +++ b/Pilz.Networking/Api/DefaultMessageSerializer.cs @@ -0,0 +1,14 @@ +namespace Pilz.Networking.Api; + +public class DefaultMessageSerializer : IMessageSerializer +{ + public ApiMessage? Deserialize(string json) + { + // ... + } + + public string? Serialize(ApiMessage message) + { + // ... + } +} diff --git a/Pilz.Networking/Api/IApiClient.cs b/Pilz.Networking/Api/IApiClient.cs new file mode 100644 index 0000000..3204398 --- /dev/null +++ b/Pilz.Networking/Api/IApiClient.cs @@ -0,0 +1,6 @@ +namespace Pilz.Networking.Api; + +public interface IApiClient +{ + void MakeRequest(string url, T message) where T : ApiMessage; +} diff --git a/Pilz.Networking/Api/IApiServer.cs b/Pilz.Networking/Api/IApiServer.cs new file mode 100644 index 0000000..dfdc4b6 --- /dev/null +++ b/Pilz.Networking/Api/IApiServer.cs @@ -0,0 +1,7 @@ +namespace Pilz.Networking.Api; + +public interface IApiServer : IApiClient +{ + void RegisterHandler(string url, T instance) where T : class; + void RegisterHandler(string url, Delegate handler); +} diff --git a/Pilz.Networking/Api/IMessageSerializer.cs b/Pilz.Networking/Api/IMessageSerializer.cs new file mode 100644 index 0000000..84597fa --- /dev/null +++ b/Pilz.Networking/Api/IMessageSerializer.cs @@ -0,0 +1,7 @@ +namespace Pilz.Networking.Api; + +public interface IMessageSerializer +{ + string? Serialize(ApiMessage message); + ApiMessage? Deserialize(string json); +} diff --git a/Pilz.Networking/Api/MessageHandlerAttribute.cs b/Pilz.Networking/Api/MessageHandlerAttribute.cs new file mode 100644 index 0000000..c82283b --- /dev/null +++ b/Pilz.Networking/Api/MessageHandlerAttribute.cs @@ -0,0 +1,8 @@ +namespace Pilz.Networking.Api; + +[AttributeUsage(AttributeTargets.Method)] +public class MessageHandlerAttribute(string url) : Attribute +{ + public string Url { get; set; } = url; + public Type? Serializer { get; set; } +} diff --git a/Pilz.Networking/Pilz.Networking.csproj b/Pilz.Networking/Pilz.Networking.csproj index ba2bb7b..cad8bb1 100644 --- a/Pilz.Networking/Pilz.Networking.csproj +++ b/Pilz.Networking/Pilz.Networking.csproj @@ -5,6 +5,7 @@ net8.0-windows latest enable + enable