From 1b1b515ee08ed1c9e0d007957f2e1514b8a034ca Mon Sep 17 00:00:00 2001 From: mauroservienti Date: Fri, 12 Mar 2021 17:02:21 +0100 Subject: [PATCH 1/6] Add support for RouteAttribute --- .../EndpointsExtensions.cs | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/ServiceComposer.AspNetCore/EndpointsExtensions.cs b/src/ServiceComposer.AspNetCore/EndpointsExtensions.cs index 36c488bc..810bb99c 100644 --- a/src/ServiceComposer.AspNetCore/EndpointsExtensions.cs +++ b/src/ServiceComposer.AspNetCore/EndpointsExtensions.cs @@ -213,8 +213,9 @@ private static CompositionEndpointBuilder CreateCompositionEndpointBuilder( }; builder.Metadata.Add(methodMetadata); - var attributes = componentsGroup.SelectMany(component => component.Method.GetCustomAttributes()); - foreach (var attribute in attributes) + var methodAttributes = componentsGroup.SelectMany(component => component.Method.GetCustomAttributes()); + var classAttributes = componentsGroup.SelectMany(component => component.ComponentType.GetCustomAttributes()); + foreach (var attribute in methodAttributes.Concat(classAttributes)) { builder.Metadata.Add(attribute); } @@ -230,9 +231,13 @@ private static CompositionEndpointBuilder CreateCompositionEndpointBuilder( { var method = ExtractMethod(componentType); var template = method.GetCustomAttribute()?.Template.TrimStart('/'); - if (template != null && useCaseInsensitiveRouteMatching) + if (template != null) { - template = template.ToLowerInvariant(); + template = PrefixWithRouteTemplateIfAny(componentType, template); + if (useCaseInsensitiveRouteMatching) + { + template = template.ToLowerInvariant(); + } } return (componentType, method, template); @@ -243,6 +248,17 @@ private static CompositionEndpointBuilder CreateCompositionEndpointBuilder( return getComponentsGroupedByTemplate; } + static string PrefixWithRouteTemplateIfAny(Type componentType, string template) + { + var routeTemplate = componentType.GetCustomAttribute()?.Template; + if (routeTemplate == null) + { + return template; + } + + return string.Concat(routeTemplate.Trim('/'), "/", template); + } + static MethodInfo ExtractMethod(Type componentType) { if (typeof(ICompositionRequestsHandler).IsAssignableFrom(componentType)) From 12b75f8bd05f597b9314293116b071e2330351d4 Mon Sep 17 00:00:00 2001 From: mauroservienti Date: Fri, 12 Mar 2021 17:05:07 +0100 Subject: [PATCH 2/6] Change a test to use the RouteAttribute --- .../Get_with_2_handlers.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ServiceComposer.AspNetCore.Endpoints.Tests/Get_with_2_handlers.cs b/src/ServiceComposer.AspNetCore.Endpoints.Tests/Get_with_2_handlers.cs index 249b1f51..db494a8a 100644 --- a/src/ServiceComposer.AspNetCore.Endpoints.Tests/Get_with_2_handlers.cs +++ b/src/ServiceComposer.AspNetCore.Endpoints.Tests/Get_with_2_handlers.cs @@ -11,6 +11,7 @@ namespace ServiceComposer.AspNetCore.Endpoints.Tests { public class Get_with_2_handlers { + [Route("sample")] class TestGetIntegerHandler : ICompositionRequestsHandler { class Model @@ -18,7 +19,7 @@ class Model [FromRoute]public int id { get; set; } } - [HttpGet("/sample/{id}")] + [HttpGet("/{id}")] public async Task Handle(HttpRequest request) { var model = await request.Bind(); @@ -27,9 +28,10 @@ public async Task Handle(HttpRequest request) } } + [Route("/sample/")] class TestGetStringHandler : ICompositionRequestsHandler { - [HttpGet("/sample/{id}")] + [HttpGet("{id}")] public Task Handle(HttpRequest request) { var vm = request.GetComposedResponseModel(); From ddf2378e66615bf4cc480d5ca51675b3721ba202 Mon Sep 17 00:00:00 2001 From: mauroservienti Date: Mon, 15 Mar 2021 16:45:56 +0100 Subject: [PATCH 3/6] Stop trimming attribute routing "/" prefix --- src/ServiceComposer.AspNetCore/EndpointsExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ServiceComposer.AspNetCore/EndpointsExtensions.cs b/src/ServiceComposer.AspNetCore/EndpointsExtensions.cs index 810bb99c..57cfdd9c 100644 --- a/src/ServiceComposer.AspNetCore/EndpointsExtensions.cs +++ b/src/ServiceComposer.AspNetCore/EndpointsExtensions.cs @@ -230,7 +230,7 @@ private static CompositionEndpointBuilder CreateCompositionEndpointBuilder( .Select(componentType => { var method = ExtractMethod(componentType); - var template = method.GetCustomAttribute()?.Template.TrimStart('/'); + var template = method.GetCustomAttribute()?.Template; if (template != null) { template = PrefixWithRouteTemplateIfAny(componentType, template); From 607e4b372f7fe842f8b1f863c8e775204609aa60 Mon Sep 17 00:00:00 2001 From: mauroservienti Date: Mon, 15 Mar 2021 16:46:30 +0100 Subject: [PATCH 4/6] Implement support for routing rules --- src/ServiceComposer.AspNetCore/EndpointsExtensions.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ServiceComposer.AspNetCore/EndpointsExtensions.cs b/src/ServiceComposer.AspNetCore/EndpointsExtensions.cs index 57cfdd9c..d8238a9c 100644 --- a/src/ServiceComposer.AspNetCore/EndpointsExtensions.cs +++ b/src/ServiceComposer.AspNetCore/EndpointsExtensions.cs @@ -250,13 +250,18 @@ private static CompositionEndpointBuilder CreateCompositionEndpointBuilder( static string PrefixWithRouteTemplateIfAny(Type componentType, string template) { + if (template.StartsWith('/') || template.StartsWith("~/")) + { + return template; + } + var routeTemplate = componentType.GetCustomAttribute()?.Template; if (routeTemplate == null) { return template; } - return string.Concat(routeTemplate.Trim('/'), "/", template); + return string.Concat(routeTemplate, "/", template); } static MethodInfo ExtractMethod(Type componentType) From 936cd05d4ceb643f573ed17736950a5004d5c63f Mon Sep 17 00:00:00 2001 From: mauroservienti Date: Mon, 15 Mar 2021 16:47:06 +0100 Subject: [PATCH 5/6] Normalize attribute usage across handlers in the same test --- .../Get_with_2_handlers.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ServiceComposer.AspNetCore.Endpoints.Tests/Get_with_2_handlers.cs b/src/ServiceComposer.AspNetCore.Endpoints.Tests/Get_with_2_handlers.cs index db494a8a..f0cdc430 100644 --- a/src/ServiceComposer.AspNetCore.Endpoints.Tests/Get_with_2_handlers.cs +++ b/src/ServiceComposer.AspNetCore.Endpoints.Tests/Get_with_2_handlers.cs @@ -19,7 +19,7 @@ class Model [FromRoute]public int id { get; set; } } - [HttpGet("/{id}")] + [HttpGet("{id}")] public async Task Handle(HttpRequest request) { var model = await request.Bind(); @@ -28,7 +28,7 @@ public async Task Handle(HttpRequest request) } } - [Route("/sample/")] + [Route("sample")] class TestGetStringHandler : ICompositionRequestsHandler { [HttpGet("{id}")] From f97788772eb0e74f7db0935884eccbc38a8b6f9e Mon Sep 17 00:00:00 2001 From: mauroservienti Date: Mon, 15 Mar 2021 17:57:26 +0100 Subject: [PATCH 6/6] Trim forward "/" once the template is built --- src/ServiceComposer.AspNetCore/EndpointsExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ServiceComposer.AspNetCore/EndpointsExtensions.cs b/src/ServiceComposer.AspNetCore/EndpointsExtensions.cs index d8238a9c..d9dc9e3b 100644 --- a/src/ServiceComposer.AspNetCore/EndpointsExtensions.cs +++ b/src/ServiceComposer.AspNetCore/EndpointsExtensions.cs @@ -240,7 +240,7 @@ private static CompositionEndpointBuilder CreateCompositionEndpointBuilder( } } - return (componentType, method, template); + return (componentType, method, template?.TrimStart('/')); }) .Where(component => component.Template != null) .GroupBy(component => component.Template);