-
-
Notifications
You must be signed in to change notification settings - Fork 73
/
Copy pathEndpointRouteBuilderGrpcExtensions.cs
61 lines (54 loc) · 3.22 KB
/
EndpointRouteBuilderGrpcExtensions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
using System.Reflection;
using Havit.ComponentModel;
using Havit.Diagnostics.Contracts;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Routing;
namespace Havit.Blazor.Grpc.Server;
public static class EndpointRouteBuilderGrpcExtensions
{
/// <summary>
/// Maps gRPC services with <see cref="ApiContractAttribute"/> as route endpoints.
/// </summary>
/// <param name="builder">Endpoint route builder.</param>
/// <param name="assemblyToScan">Assembly to scan for interfaces with <see cref="ApiContractAttribute"/>.</param>
/// <param name="configureEndpointWithAuthorization">Optional configuration for endpoints with authorization (all except <c>[ApiContract(RequireAuthorization = false)]</c>). Usually you want to setup <c>endpoint.RequireAuthorization(...)</c> here."/></param>
/// <param name="configureEndpointAll">Optional configuration for all endpoints.</param>
public static void MapGrpcServicesByApiContractAttributes(
this IEndpointRouteBuilder builder,
Assembly assemblyToScan,
Action<GrpcServiceEndpointConventionBuilder> configureEndpointWithAuthorization = null,
Action<GrpcServiceEndpointConventionBuilder> configureEndpointAll = null)
{
MapGrpcServicesByApiContractAttributes(builder, [assemblyToScan], configureEndpointWithAuthorization, configureEndpointAll);
}
/// <summary>
/// Maps gRPC services with <see cref="ApiContractAttribute"/> as route endpoints.
/// </summary>
/// <param name="builder">Endpoint route builder.</param>
/// <param name="assembliesToScan">Assemblies to scan for interfaces with <see cref="ApiContractAttribute"/>.</param>
/// <param name="configureEndpointWithAuthorization">Optional configuration for endpoints with authorization (all except <c>[ApiContract(RequireAuthorization = false)]</c>). Usually you want to setup <c>endpoint.RequireAuthorization(...)</c> here."/></param>
/// <param name="configureEndpointAll">Optional configuration for all endpoints.</param>
public static void MapGrpcServicesByApiContractAttributes(
this IEndpointRouteBuilder builder,
Assembly[] assembliesToScan,
Action<GrpcServiceEndpointConventionBuilder> configureEndpointWithAuthorization = null,
Action<GrpcServiceEndpointConventionBuilder> configureEndpointAll = null)
{
Contract.Requires<ArgumentNullException>(builder is not null, nameof(builder));
Contract.Requires<ArgumentNullException>(assembliesToScan is not null, nameof(assembliesToScan));
var interfacesAndAttributes = (from assembly in assembliesToScan
from type in assembly.GetTypes()
from apiContractAttribute in type.GetCustomAttributes(typeof(ApiContractAttribute), false).Cast<ApiContractAttribute>()
select new { Interface = type, Attribute = apiContractAttribute }).ToArray();
var mapGrpcServiceMethodInfo = typeof(GrpcEndpointRouteBuilderExtensions).GetMethod(nameof(GrpcEndpointRouteBuilderExtensions.MapGrpcService));
foreach (var item in interfacesAndAttributes)
{
var endpoint = (GrpcServiceEndpointConventionBuilder)mapGrpcServiceMethodInfo.MakeGenericMethod(item.Interface).Invoke(null, new[] { builder });
configureEndpointAll?.Invoke(endpoint);
if (item.Attribute.RequireAuthorization)
{
configureEndpointWithAuthorization?.Invoke(endpoint);
}
}
}
}