Initial version

This commit is contained in:
2026-06-09 22:27:38 +02:00
parent 5afbf3b01c
commit 5ff2ac8941
57 changed files with 2343 additions and 98 deletions
+36
View File
@@ -0,0 +1,36 @@
using System.Runtime.Serialization;
using System.ServiceModel;
using ProtoBuf.Grpc;
namespace EonaCat.gRPC.Proto
{
public class Authentication
{
}
[ServiceContract]
public interface IAuthenticationService
{
[OperationContract]
Task<AuthenticationResponse> Authenticate(AuthenticationRequest request, CallContext context = default);
}
[DataContract]
public class AuthenticationRequest
{
[DataMember(Order = 1)]
public string UserName { get; set; } = null!;
[DataMember(Order = 2)]
public string Password { get; set; } = null!;
}
[DataContract]
public class AuthenticationResponse
{
[DataMember(Order = 1)]
public string AccessToken { get; set; } = null!;
[DataMember(Order = 2)]
public int ExpiresIn { get; set; }
}
}
+126
View File
@@ -0,0 +1,126 @@
using ProtoBuf;
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace EonaCat.gRPC.Proto;
[ProtoContract]
public class BaseResponse<T>
{
[ProtoMember(1)]
public bool IsSuccess { get; set; }
[ProtoMember(2)]
public string? Message { get; set; }
[ProtoMember(3)]
public T? Data { get; set; }
public static BaseResponse<T?> Ok(T? data, string? message = null)
{
return new BaseResponse<T?>
{
IsSuccess = true,
Message = message,
Data = data
};
}
public static BaseResponse<T> Created(T? data, string? message = null)
{
return new BaseResponse<T>
{
IsSuccess = true,
Message = string.IsNullOrEmpty(message)
? ConstructMessage(GetCallingClassName())
: message,
Data = data
};
}
public static BaseResponse<T> Updated(T? data, string? message = null)
{
return new BaseResponse<T>
{
IsSuccess = true,
Message = string.IsNullOrEmpty(message)
? ConstructMessage(GetCallingClassName())
: message,
Data = data
};
}
public static BaseResponse<T> Deleted(T? data, string? message = null)
{
return new BaseResponse<T>
{
IsSuccess = true,
Message = string.IsNullOrEmpty(message)
? ConstructMessage(GetCallingClassName())
: message,
Data = data
};
}
public static BaseResponse<T> Failed(T? data, string? message = null, [CallerMemberName] string actionName = "")
{
return new BaseResponse<T>
{
IsSuccess = false,
Message = string.IsNullOrEmpty(message)
? ConstructMessage(GetCallingClassName(), false, actionName)
: message,
Data = data
};
}
#region Private Methods
private static string ConstructMessage(string callerName, bool isSuccess = true, [CallerMemberName] string actionName = "")
{
var messageStatus = isSuccess ? "Successfully" : "Failed";
try
{
if (callerName.Contains("Service"))
{
var entityName = callerName[..^7];
return $"{entityName} {actionName} {messageStatus}";
}
return $"{actionName} {messageStatus}";
}
catch (Exception)
{
// Ignore the exception...
return $"{actionName} {messageStatus}";
}
}
private static string GetCallingClassName()
{
string fullName;
Type declaringType;
var skipFrames = 2;
try
{
do
{
var method = new StackFrame(skipFrames, false).GetMethod();
declaringType = method.DeclaringType;
if (declaringType == null)
{
return method.Name;
}
skipFrames++;
fullName = declaringType.ReflectedType?.Name;
}
while (declaringType.Module.Name.Equals("mscorlib.dll", StringComparison.OrdinalIgnoreCase));
return fullName;
}
catch (Exception)
{
return string.Empty;
}
}
#endregion
}
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="protobuf-net.Grpc" Version="1.2.2" />
<PackageReference Include="protobuf-net.Grpc.AspNetCore" Version="1.2.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\EonaCat.gRPC.Core\EonaCat.gRPC.Core.csproj" />
</ItemGroup>
</Project>
+44
View File
@@ -0,0 +1,44 @@
using ProtoBuf;
namespace EonaCat.gRPC.Proto.Helpers;
public static class Utility
{
public static byte[] ProtoSerialize<T>(T record) where T : class
{
if (null == record) return null;
try
{
using (var stream = new MemoryStream())
{
Serializer.Serialize(stream, record);
return stream.ToArray();
}
}
catch
{
// Log error
throw;
}
}
public static T ProtoDeserialize<T>(byte[] data) where T : class
{
if (null == data) return null;
try
{
using (var stream = new MemoryStream(data))
{
return Serializer.Deserialize<T>(stream);
}
}
catch
{
// Log error
throw;
}
}
}
+49
View File
@@ -0,0 +1,49 @@
using System.ServiceModel;
using ProtoBuf;
using EonaCat.gRPC.Core.Entities;
namespace EonaCat.gRPC.Proto;
public class User
{
}
[ServiceContract]
public interface IProtoUserService
{
[OperationContract]
ValueTask<BaseResponse<string>> Create(UserCreateRequest userCreateRequest);
[OperationContract]
Task<BaseResponse<UserResponse?>> GetByIdAsync(string id);
[OperationContract]
Task<BaseResponse<List<UserResponse>?>> GetAsync();
}
[ProtoContract]
public class UserResponse
{
[ProtoMember(1)]
public string Id { get; set; } = null!;
[ProtoMember(2)]
public string? FirstName { get; set; }
[ProtoMember(3)]
public string? LastName { get; set; }
[ProtoMember(4)]
public string Email { get; set; } = null!;
}
[ProtoContract]
public class UserCreateRequest
{
[ProtoMember(1)]
public string? FirstName { get; set; }
[ProtoMember(2)]
public string? LastName { get; set; }
[ProtoMember(3)]
public string? Email { get; set; }
}