Skip to content

Commit

Permalink
Merge pull request #120 from itsharppro/dev
Browse files Browse the repository at this point in the history
(#118) (#119) update webApi and cqrs webApi
  • Loading branch information
DevITSharpPRO authored Oct 4, 2024
2 parents 4a45223 + 3d1ee48 commit 22a37b8
Show file tree
Hide file tree
Showing 16 changed files with 265 additions and 128 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,25 @@ public async Task<TResult> QueryAsync<TResult>(IQuery<TResult> query, Cancellati
using var scope = _serviceProvider.CreateScope();
var handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResult));
var handler = scope.ServiceProvider.GetRequiredService(handlerType);

var handleAsyncMethod = handlerType.GetMethod(nameof(IQueryHandler<IQuery<TResult>, TResult>.HandleAsync));

if (handleAsyncMethod == null)
{
throw new InvalidOperationException($"Handler for query '{query.GetType().Name}' does not contain a valid 'HandleAsync' method.");
}

var resultTask = (Task<TResult>?)handleAsyncMethod.Invoke(handler, new object[] { query, cancellationToken });

if (resultTask == null)
{
throw new InvalidOperationException($"HandleAsync method for '{query.GetType().Name}' returned null.");
}

return await resultTask;
// We get the 'HandleAsync' method directly from the handler
var handleAsyncMethod = handlerType.GetMethod(nameof(IQueryHandler<IQuery<TResult>, TResult>.HandleAsync));
// if (handleAsyncMethod == null)
// {
// throw new InvalidOperationException($"Handler for query '{query.GetType().Name}' does not contain a valid 'HandleAsync' method.");
// }

// var taskResult = handleAsyncMethod.Invoke(handler, new object[] { query, cancellationToken });

// if (taskResult is Task<TResult> resultTask)
// {
// return await resultTask;
// }

// throw new InvalidOperationException($"HandleAsync method for '{query.GetType().Name}' returned an invalid result.");
return await (Task<TResult>) handlerType
.GetMethod(nameof(IQueryHandler<IQuery<TResult>, TResult>.HandleAsync))?
.Invoke(handler, new object[] {query, cancellationToken});
}

public async Task<TResult> QueryAsync<TQuery, TResult>(TQuery query, CancellationToken cancellationToken = default)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
using NetJSON;
using Paralax.CQRS.Commands;
using Paralax.CQRS.Queries;
using Paralax.WebApi;
using Paralax.CQRS.WebApi;

namespace Paralax.WebApi.CQRS.Builders
namespace Paralax.CQRS.WebApi.Builders
{
public class DispatcherEndpointsBuilder : IDispatcherEndpointsBuilder
{
Expand Down Expand Up @@ -49,7 +51,8 @@ public IDispatcherEndpointsBuilder Get<TQuery, TResult>(string path,
return;
}

await WriteJsonAsync(ctx.Response, result);
// await WriteJsonAsync(ctx.Response, result);
await ctx.Response.WriteJsonAsync(result);
return;
}

Expand Down Expand Up @@ -137,11 +140,17 @@ private static async Task BuildCommandContext<T>(T command, HttpContext context,

private static async Task WriteJsonAsync(HttpResponse response, object result)
{
NetJSON.NetJSON.DateFormat = NetJSON.NetJSONDateFormat.ISO;
NetJSON.NetJSON.SkipDefaultValue = false;

response.ContentType = "application/json";

var json = NetJSON.NetJSON.Serialize(result);

await response.WriteAsync(json);
}


private static async Task<T> ReadJsonAsync<T>(HttpContext context) where T : class
{
var body = await new StreamReader(context.Request.Body).ReadToEndAsync();
Expand Down
6 changes: 3 additions & 3 deletions src/Paralax.CQRS.WebApi/src/Paralax.CQRS.WebApi/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
using Microsoft.Extensions.DependencyInjection;
using Paralax.CQRS.Commands;
using Paralax.CQRS.Queries;
using Paralax.CQRS.WebApi.Builders;
using Paralax.CQRS.WebApi.Middlewares;
using Paralax.WebApi;
using Paralax.WebApi.CQRS;
using Paralax.WebApi.CQRS.Builders;
using Paralax.WebApi.CQRS.Middlewares;


namespace Paralax.CQRS.WebApi
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;

namespace Paralax.WebApi.CQRS
namespace Paralax.CQRS.WebApi
{
public interface IDispatcherEndpointsBuilder
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
using System.Threading.Tasks;
using System.Reflection;

namespace Paralax.WebApi.CQRS.Middlewares
namespace Paralax.CQRS.WebApi.Middlewares
{
public class PublicContractsMiddleware
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System.IO;
using System.Threading.Tasks;
using MessagePack;
using MessagePack.Resolvers;

namespace Paralax.HTTP
{
public class MessagePackHttpClientSerializer : IHttpClientSerializer
{
private readonly MessagePackSerializerOptions _options;

public MessagePackHttpClientSerializer(MessagePackSerializerOptions options = null)
{
_options = options ?? MessagePackSerializerOptions.Standard
.WithResolver(ContractlessStandardResolver.Instance)
.WithCompression(MessagePackCompression.Lz4BlockArray)
.WithSecurity(MessagePackSecurity.UntrustedData);
}

public string Serialize<T>(T value)
{
var bytes = MessagePackSerializer.Serialize(value, _options);
return System.Convert.ToBase64String(bytes);
}

public async Task SerializeAsync<T>(Stream stream, T value)
{
await MessagePackSerializer.SerializeAsync(stream, value, _options);
}

public async ValueTask<T> DeserializeAsync<T>(Stream stream)
{
return await MessagePackSerializer.DeserializeAsync<T>(stream, _options);
}

public T Deserialize<T>(string base64)
{
var bytes = System.Convert.FromBase64String(base64);
return MessagePackSerializer.Deserialize<T>(bytes, _options);
}
}
}
29 changes: 21 additions & 8 deletions src/Paralax.HTTP/src/Paralax.HTTP/NetJsonHttpClientSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,26 @@ public NetJsonHttpClientSerializer(NetJSONSettings settings = null)
{
_settings = settings ?? new NetJSONSettings
{
UseEnumString = true,
CaseSensitive = false,
SkipDefaultValue = true
UseEnumString = true,
CaseSensitive = false,
SkipDefaultValue = false,
DateFormat = NetJSONDateFormat.ISO,
TimeZoneFormat = NetJSONTimeZoneFormat.Utc
};
}

public string Serialize<T>(T value) => NetJSON.NetJSON.Serialize(value, _settings);
public string Serialize<T>(T value)
{
return NetJSON.NetJSON.Serialize(value, _settings);
}

public async Task SerializeAsync<T>(Stream stream, T value)
{
using (var writer = new StreamWriter(stream))
var json = NetJSON.NetJSON.Serialize(value, _settings);

using (var writer = new StreamWriter(stream))
{
await writer.WriteAsync(NetJSON.NetJSON.Serialize(value, _settings));
await writer.WriteAsync(json);
await writer.FlushAsync();
}
}
Expand All @@ -34,10 +41,16 @@ public async ValueTask<T> DeserializeAsync<T>(Stream stream)
using (var reader = new StreamReader(stream))
{
var content = await reader.ReadToEndAsync();
return NetJSON.NetJSON.Deserialize<T>(content, _settings);

var result = NetJSON.NetJSON.Deserialize<T>(content, _settings);

return result;
}
}

public T Deserialize<T>(string json) => NetJSON.NetJSON.Deserialize<T>(json, _settings);
public T Deserialize<T>(string json)
{
return NetJSON.NetJSON.Deserialize<T>(json, _settings);
}
}
}
2 changes: 2 additions & 0 deletions src/Paralax.HTTP/src/Paralax.HTTP/Paralax.HTTP.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
<PackagePath>\</PackagePath>
</None>

<PackageReference Include="MessagePack" Version="2.5.172" />

<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="NetJSON" Version="1.4.4" />
Expand Down
10 changes: 2 additions & 8 deletions src/Paralax.HTTP/src/Paralax.HTTP/ParalaxHttpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ private async Task<HttpResult<T>> CreateHttpResult<T>(HttpResponseMessage respon
var stream = await response.Content.ReadAsStreamAsync();
serializer ??= _serializer;
var result = await serializer.DeserializeAsync<T>(stream);
Console.WriteLine($"Deserialized Result: {result}");

return new HttpResult<T>(result, response);
}
Expand All @@ -198,7 +199,6 @@ private StringContent GetJsonPayload(object data, IHttpClientSerializer serializ
return content;
}

// Retry policy using Polly
private async Task<T> RetryPolicy<T>(Func<Task<T>> action)
{
return await Policy
Expand All @@ -209,22 +209,18 @@ private async Task<T> RetryPolicy<T>(Func<Task<T>> action)

protected virtual async Task<HttpResult<T>> SendResultAsync<T>(string uri, Method method, HttpContent content = null, IHttpClientSerializer serializer = null)
{
// Sending the request using the method and content
var response = await SendAsync(uri, method, content);

// If the response status code is not successful, return a default result
if (!response.IsSuccessStatusCode)
{
return new HttpResult<T>(default, response);
}

// Read the response content stream
var stream = await response.Content.ReadAsStreamAsync();

// Deserialize the stream using the provided serializer (or default to _serializer)
var result = await DeserializeJsonFromStream<T>(stream, serializer);
Console.WriteLine($"Deserialized Result: {result}");

// Return the deserialized result along with the response
return new HttpResult<T>(result, response);
}

Expand All @@ -235,7 +231,6 @@ private async Task<T> DeserializeJsonFromStream<T>(Stream stream, IHttpClientSer
return default;
}

// Use the provided serializer or default to _serializer
serializer ??= _serializer;

return await serializer.DeserializeAsync<T>(stream);
Expand All @@ -253,7 +248,6 @@ public enum Method
}
}

// Extension method for converting Method enum to HttpMethod
internal static class MethodExtensions
{
public static HttpMethod ToHttpMethod(this ParalaxHttpClient.Method method)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,21 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using NetJSON;
using Open.Serialization.Json;

namespace Paralax.WebApi.Exceptions
{
internal sealed class ErrorHandlerMiddleware : IMiddleware
{
private readonly IExceptionToResponseMapper _exceptionToResponseMapper;
private readonly IJsonSerializer _jsonSerializer;
private readonly ILogger<ErrorHandlerMiddleware> _logger;

public ErrorHandlerMiddleware(IExceptionToResponseMapper exceptionToResponseMapper,
ILogger<ErrorHandlerMiddleware> logger)
IJsonSerializer jsonSerializer, ILogger<ErrorHandlerMiddleware> logger)
{
_exceptionToResponseMapper = exceptionToResponseMapper;
_jsonSerializer = jsonSerializer;
_logger = logger;
}

Expand All @@ -28,7 +30,7 @@ public async Task InvokeAsync(HttpContext context, RequestDelegate next)
catch (Exception exception)
{
_logger.LogError(exception, "An error occurred while processing the request.");
await HandleErrorAsync(context, exception); // Handle the error when caught
await HandleErrorAsync(context, exception);
}
}

Expand All @@ -48,10 +50,7 @@ private async Task HandleErrorAsync(HttpContext context, Exception exception)

context.Response.ContentType = "application/json";

// Use NetJSON to serialize the response
var jsonResponse = NetJSON.NetJSON.Serialize(response);

await context.Response.WriteAsync(jsonResponse);
await _jsonSerializer.SerializeAsync(context.Response.Body, response);
}
}
}
Loading

0 comments on commit 22a37b8

Please sign in to comment.