Skip to content

Commit

Permalink
fix(source generators): resolve AsyncEnumerable issues of HttpClientP…
Browse files Browse the repository at this point in the history
…roxyGenerator #6369 (#6370)
  • Loading branch information
ysmoradi authored Dec 21, 2023
1 parent 4701419 commit c122100
Show file tree
Hide file tree
Showing 12 changed files with 33 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ public class ControllerAction

public bool DoesReturnSomething => ReturnType.ToDisplayString() is not "System.Threading.Tasks.Task" or "System.Threading.Tasks.ValueTask";

public bool DoesReturnIAsyncEnumerable => DoesReturnSomething && ReturnType.ToDisplayString().Contains("IAsyncEnumerable");

public string HttpMethod { get; set; } = default!;

public string Url { get; set; } = default!;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ public void Execute(GeneratorExecutionContext context)
{{" : string.Empty)}
using var request = new HttpRequestMessage(HttpMethod.{action.HttpMethod}, url);
{(action.BodyParameter is not null ? $@"request.Content = JsonContent.Create({action.BodyParameter.Name}, options.GetTypeInfo<{action.BodyParameter.Type.ToDisplayString()}>());" : string.Empty)}
using var response = await httpClient.SendAsync(request{(action.HasCancellationToken ? $", {action.CancellationTokenParameterName}" : string.Empty)});
{(action.DoesReturnSomething ? ($"return await response.Content.ReadFromJsonAsync(options.GetTypeInfo<{action.ReturnType.GetUnderlyingType().ToDisplayString()}>(){(action.HasCancellationToken ? $", {action.CancellationTokenParameterName}" : string.Empty)});}}))!;") : string.Empty)}
{(action.DoesReturnIAsyncEnumerable ? "" : "using ")}var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead {(action.HasCancellationToken ? $", {action.CancellationTokenParameterName}" : string.Empty)});
{(action.DoesReturnSomething ? ($"return {(action.DoesReturnIAsyncEnumerable ? "" : "await")} response.Content.{(action.DoesReturnIAsyncEnumerable ? "ReadFromJsonAsAsyncEnumerable" : "ReadFromJsonAsync")}(options.GetTypeInfo<{action.ReturnType.GetUnderlyingType().ToDisplayString()}>(){(action.HasCancellationToken ? $", {action.CancellationTokenParameterName}" : string.Empty)});" +
$"}}))!;") : string.Empty)}
}}
");
}
Expand Down Expand Up @@ -114,7 +115,6 @@ public void AddQueryStrings(Dictionary<string, object?> queryString)
}}
");

context.AddSource($"HttpClientProxy.cs", finalSource.ToString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,16 @@ public static string GetHttpMethod(this IMethodSymbol method)

public static ITypeSymbol GetUnderlyingType(this ITypeSymbol typeSymbol)
{
return typeSymbol switch
if (typeSymbol is INamedTypeSymbol namedTypeSymbol)
{
INamedTypeSymbol namedTypeSymbol => namedTypeSymbol.TypeArguments.FirstOrDefault() ?? namedTypeSymbol,
_ => typeSymbol
};
if (namedTypeSymbol.ToDisplayString().Contains("System.Collections.Generic.IAsyncEnumerable<"))
{
return namedTypeSymbol.TypeArguments.First().GetUnderlyingType();
}

return namedTypeSymbol.TypeArguments.FirstOrDefault() ?? namedTypeSymbol;
}

return typeSymbol;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public async Task<PagedResult<CategoryDto>> GetCategories(ODataQueryOptions<Cate
if (odataQuery.Top is not null)
query = query.Take(odataQuery.Top.Value);

return new PagedResult<CategoryDto>(query.AsAsyncEnumerable(), totalCount);
return new PagedResult<CategoryDto>(await query.ToArrayAsync(cancellationToken), totalCount);
}

[HttpGet("{id}")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public async Task<PagedResult<ProductDto>> GetProducts(ODataQueryOptions<Product
if (odataQuery.Top is not null)
query = query.Take(odataQuery.Top.Value);

return new PagedResult<ProductDto>(query.AsAsyncEnumerable(), totalCount);
return new PagedResult<ProductDto>(await query.ToArrayAsync(cancellationToken), totalCount);
}

[HttpGet("{id}")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public async Task<PagedResult<TodoItemDto>> GetTodoItems(ODataQueryOptions<TodoI
if (odataQuery.Top is not null)
query = query.Take(odataQuery.Top.Value);

return new PagedResult<TodoItemDto>(query.AsAsyncEnumerable(), totalCount);
return new PagedResult<TodoItemDto>(await query.ToArrayAsync(cancellationToken), totalCount);
}

[HttpGet("{id}")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,17 @@ namespace Boilerplate.Shared.Dtos;
[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
[JsonSerializable(typeof(Dictionary<string, object>))]
[JsonSerializable(typeof(UserDto))]
[JsonSerializable(typeof(List<UserDto>))]
//#if (sample == "Todo")
[JsonSerializable(typeof(TodoItemDto))]
[JsonSerializable(typeof(List<TodoItemDto>))]
[JsonSerializable(typeof(PagedResult<TodoItemDto>))]
//#elif (sample == "Admin")
[JsonSerializable(typeof(ProductsCountPerCategoryResponseDto))]
[JsonSerializable(typeof(OverallAnalyticsStatsDataResponseDto))]
[JsonSerializable(typeof(List<ProductsCountPerCategoryResponseDto>))]
[JsonSerializable(typeof(List<ProductSaleStatResponseDto>))]
[JsonSerializable(typeof(List<ProductPercentagePerCategoryResponseDto>))]
[JsonSerializable(typeof(ProductSaleStatResponseDto))]
[JsonSerializable(typeof(ProductPercentagePerCategoryResponseDto))]
[JsonSerializable(typeof(ProductDto))]
[JsonSerializable(typeof(List<ProductDto>))]
[JsonSerializable(typeof(PagedResult<ProductDto>))]
[JsonSerializable(typeof(CategoryDto))]
[JsonSerializable(typeof(List<CategoryDto>))]
[JsonSerializable(typeof(PagedResult<CategoryDto>))]
//#endif
[JsonSerializable(typeof(SignInRequestDto))]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,14 @@

public class PagedResult<T>
{
public IAsyncEnumerable<T>? Items { get; set; }
public T[] Items { get; set; } = [];

public long TotalCount { get; set; }

public PagedResult(IAsyncEnumerable<T> items, long totalCount)
[JsonConstructor]
public PagedResult(T[] items, long totalCount)
{
Items = items;
TotalCount = totalCount;
}

public PagedResult()
{

}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace Boilerplate.Client.Core.Components;
using System.Text.Json;

namespace Boilerplate.Client.Core.Components;

public partial class AppComponentBase : ComponentBase, IDisposable
{
Expand All @@ -8,6 +10,8 @@ public partial class AppComponentBase : ComponentBase, IDisposable

[AutoInject] protected HttpClient HttpClient = default!;

[AutoInject] protected JsonSerializerOptions JsonSerializerOptions = default!;

/// <summary>
/// <inheritdoc cref="IPrerenderStateService"/>
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ private void PrepareGridDataProvider()

var data = await categoryController.GetCategories(CurrentCancellationToken);

return BitDataGridItemsProviderResult.From(await data.Items!.ToListAsync(CurrentCancellationToken)!, (int)data.TotalCount);
return BitDataGridItemsProviderResult.From(data.Items!, (int)data.TotalCount);
}
catch (Exception exp)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ private void PrepareGridDataProvider()

var data = await productController.GetProducts(CurrentCancellationToken);

return BitDataGridItemsProviderResult.From(await data!.Items!.ToListAsync(), (int)data!.TotalCount);
return BitDataGridItemsProviderResult.From(data!.Items!, (int)data!.TotalCount);
}
catch (Exception exp)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//-:cnd:noEmit
using Microsoft.AspNetCore.Components.Web;

namespace Boilerplate.Client.Core.Services;
Expand Down

0 comments on commit c122100

Please sign in to comment.