From cd8975aac89fd16049a8e1e5ee235d7b3d254042 Mon Sep 17 00:00:00 2001 From: "yuri.voloshyn" Date: Wed, 15 May 2019 17:26:23 +0300 Subject: [PATCH 1/2] fixed issue #662 added RefitRestServiceAttribute for HttpClient relative path --- Refit.Tests/InterfaceStubGenerator.cs | 2 +- Refit.Tests/RefitStubs.Net46.cs | 64 +++++++++++++++++++++++++++ Refit.Tests/RefitStubs.NetCore2.cs | 64 +++++++++++++++++++++++++++ Refit.Tests/RestService.cs | 33 ++++++++++++++ Refit/Attributes.cs | 11 +++++ Refit/RestService.cs | 21 ++++----- 6 files changed, 184 insertions(+), 11 deletions(-) diff --git a/Refit.Tests/InterfaceStubGenerator.cs b/Refit.Tests/InterfaceStubGenerator.cs index 3ca27f283..2e0858485 100644 --- a/Refit.Tests/InterfaceStubGenerator.cs +++ b/Refit.Tests/InterfaceStubGenerator.cs @@ -126,7 +126,7 @@ public void GenerateTemplateInfoForInterfaceListSmokeTest() .ToList(); var result = fixture.GenerateTemplateInfoForInterfaceList(input); - Assert.Equal(12, result.ClassList.Count); + Assert.Equal(14, result.ClassList.Count); } [Fact] diff --git a/Refit.Tests/RefitStubs.Net46.cs b/Refit.Tests/RefitStubs.Net46.cs index 64751d66b..06826898a 100644 --- a/Refit.Tests/RefitStubs.Net46.cs +++ b/Refit.Tests/RefitStubs.Net46.cs @@ -1331,6 +1331,70 @@ Task INpmJs.GetCongruence() } } +namespace Refit.Tests +{ + using Refit.Tests.RefitInternalGenerated; + + /// + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [global::System.Diagnostics.DebuggerNonUserCode] + [Preserve] + [global::System.Reflection.Obfuscation(Exclude=true)] + partial class AutoGeneratedIRelativePathApi1 : IRelativePathApi1 + { + /// + public HttpClient Client { get; protected set; } + readonly IRequestBuilder requestBuilder; + + /// + public AutoGeneratedIRelativePathApi1(HttpClient client, IRequestBuilder requestBuilder) + { + Client = client; + this.requestBuilder = requestBuilder; + } + + /// + Task IRelativePathApi1.Get() + { + var arguments = new object[] { }; + var func = requestBuilder.BuildRestResultFuncForMethod("Get", new Type[] { }); + return (Task)func(Client, arguments); + } + } +} + +namespace Refit.Tests +{ + using Refit.Tests.RefitInternalGenerated; + + /// + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [global::System.Diagnostics.DebuggerNonUserCode] + [Preserve] + [global::System.Reflection.Obfuscation(Exclude=true)] + partial class AutoGeneratedIRelativePathApi2 : IRelativePathApi2 + { + /// + public HttpClient Client { get; protected set; } + readonly IRequestBuilder requestBuilder; + + /// + public AutoGeneratedIRelativePathApi2(HttpClient client, IRequestBuilder requestBuilder) + { + Client = client; + this.requestBuilder = requestBuilder; + } + + /// + Task IRelativePathApi2.Get() + { + var arguments = new object[] { }; + var func = requestBuilder.BuildRestResultFuncForMethod("Get", new Type[] { }); + return (Task)func(Client, arguments); + } + } +} + namespace Refit.Tests { using Refit.Tests.RefitInternalGenerated; diff --git a/Refit.Tests/RefitStubs.NetCore2.cs b/Refit.Tests/RefitStubs.NetCore2.cs index 64751d66b..06826898a 100644 --- a/Refit.Tests/RefitStubs.NetCore2.cs +++ b/Refit.Tests/RefitStubs.NetCore2.cs @@ -1331,6 +1331,70 @@ Task INpmJs.GetCongruence() } } +namespace Refit.Tests +{ + using Refit.Tests.RefitInternalGenerated; + + /// + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [global::System.Diagnostics.DebuggerNonUserCode] + [Preserve] + [global::System.Reflection.Obfuscation(Exclude=true)] + partial class AutoGeneratedIRelativePathApi1 : IRelativePathApi1 + { + /// + public HttpClient Client { get; protected set; } + readonly IRequestBuilder requestBuilder; + + /// + public AutoGeneratedIRelativePathApi1(HttpClient client, IRequestBuilder requestBuilder) + { + Client = client; + this.requestBuilder = requestBuilder; + } + + /// + Task IRelativePathApi1.Get() + { + var arguments = new object[] { }; + var func = requestBuilder.BuildRestResultFuncForMethod("Get", new Type[] { }); + return (Task)func(Client, arguments); + } + } +} + +namespace Refit.Tests +{ + using Refit.Tests.RefitInternalGenerated; + + /// + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [global::System.Diagnostics.DebuggerNonUserCode] + [Preserve] + [global::System.Reflection.Obfuscation(Exclude=true)] + partial class AutoGeneratedIRelativePathApi2 : IRelativePathApi2 + { + /// + public HttpClient Client { get; protected set; } + readonly IRequestBuilder requestBuilder; + + /// + public AutoGeneratedIRelativePathApi2(HttpClient client, IRequestBuilder requestBuilder) + { + Client = client; + this.requestBuilder = requestBuilder; + } + + /// + Task IRelativePathApi2.Get() + { + var arguments = new object[] { }; + var func = requestBuilder.BuildRestResultFuncForMethod("Get", new Type[] { }); + return (Task)func(Client, arguments); + } + } +} + namespace Refit.Tests { using Refit.Tests.RefitInternalGenerated; diff --git a/Refit.Tests/RestService.cs b/Refit.Tests/RestService.cs index 4eeb42189..98ba4a6a8 100644 --- a/Refit.Tests/RestService.cs +++ b/Refit.Tests/RestService.cs @@ -139,6 +139,24 @@ public interface ITrimTrailingForwardSlashApi Task Get(); } + [RefitRestService("/api/Test")] + public interface IRelativePathApi1 + { + HttpClient Client { get; } + + [Get("/someendpoint")] + Task Get(); + } + + [RefitRestService()] + public interface IRelativePathApi2 + { + HttpClient Client { get; } + + [Get("/someendpoint")] + Task Get(); + } + public interface IValidApi { [Get("/someendpoint")] @@ -1301,5 +1319,20 @@ public void NonGenericCreate() Assert.Equal(fixture.Client.BaseAddress.AbsoluteUri, expectedBaseAddress); } + + [Fact] + public void RelativePathCreate() + { + var inputBaseAddress = "http://example.com/"; + + var expectedBaseAddress1 = "http://example.com/api/Test"; + var expectedBaseAddress2 = "http://example.com/"; + + var fixture1 = RestService.For(inputBaseAddress); + var fixture2 = RestService.For(inputBaseAddress); + + Assert.Equal(fixture1.Client.BaseAddress.AbsoluteUri, expectedBaseAddress1); + Assert.Equal(fixture2.Client.BaseAddress.AbsoluteUri, expectedBaseAddress2); + } } } diff --git a/Refit/Attributes.cs b/Refit/Attributes.cs index f7097ece6..8389a7972 100644 --- a/Refit/Attributes.cs +++ b/Refit/Attributes.cs @@ -318,4 +318,15 @@ public QueryAttribute(CollectionFormat collectionFormat) /// public CollectionFormat CollectionFormat { get; set; } = CollectionFormat.RefitParameterFormatter; } + + [AttributeUsage(AttributeTargets.Interface)] + public class RefitRestServiceAttribute : Attribute + { + public RefitRestServiceAttribute(string relativePath = null) + { + RelativePath = relativePath; + } + + public string RelativePath { get; } + } } diff --git a/Refit/RestService.cs b/Refit/RestService.cs index 6d2e282a7..012a12e4b 100644 --- a/Refit/RestService.cs +++ b/Refit/RestService.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Net.Http; +using System.Reflection; using System.Threading.Tasks; namespace Refit @@ -18,9 +19,7 @@ public static class RestService public static T For(HttpClient client, IRequestBuilder builder) { - var generatedType = TypeMapping.GetOrAdd(typeof(T), GetGeneratedType()); - - return (T)Activator.CreateInstance(generatedType, client, builder); + return (T)For(typeof(T), client, builder); } public static T For(HttpClient client, RefitSettings settings) @@ -43,7 +42,14 @@ public static T For(string hostUrl, RefitSettings settings) public static object For(Type refitInterfaceType, HttpClient client, IRequestBuilder builder) { - var generatedType = TypeMapping.GetOrAdd(refitInterfaceType, GetGeneratedType(refitInterfaceType)); + var generatedType = TypeMapping.GetOrAdd(refitInterfaceType, type => GetGeneratedType(type)); + + var aps = refitInterfaceType.GetTypeInfo().GetCustomAttributes(true).OfType().FirstOrDefault(); + + if (aps != null && !string.IsNullOrEmpty(aps.RelativePath)) + { + client.BaseAddress = new Uri(client.BaseAddress, aps.RelativePath); + } return Activator.CreateInstance(generatedType, client, builder); } @@ -94,14 +100,9 @@ public static HttpClient CreateHttpClient(string hostUrl, RefitSettings settings return new HttpClient(innerHandler ?? new HttpClientHandler()) { BaseAddress = new Uri(hostUrl.TrimEnd('/')) }; } - static Type GetGeneratedType() - { - return GetGeneratedType(typeof(T)); - } - static Type GetGeneratedType(Type refitInterfaceType) { - string typeName = UniqueName.ForType(refitInterfaceType); + var typeName = UniqueName.ForType(refitInterfaceType); var generatedType = Type.GetType(typeName); From c5ef508d3fa5f240279f57462895783af9eaca21 Mon Sep 17 00:00:00 2001 From: "yuri.voloshyn" Date: Thu, 16 May 2019 00:39:25 +0300 Subject: [PATCH 2/2] RefitRestServiceAttribute renamed to BaseAddressAttribute --- Refit.Tests/RestService.cs | 4 ++-- Refit/Attributes.cs | 4 ++-- Refit/RestService.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Refit.Tests/RestService.cs b/Refit.Tests/RestService.cs index 98ba4a6a8..6efb7e8c1 100644 --- a/Refit.Tests/RestService.cs +++ b/Refit.Tests/RestService.cs @@ -139,7 +139,7 @@ public interface ITrimTrailingForwardSlashApi Task Get(); } - [RefitRestService("/api/Test")] + [BaseAddress("/api/Test")] public interface IRelativePathApi1 { HttpClient Client { get; } @@ -148,7 +148,7 @@ public interface IRelativePathApi1 Task Get(); } - [RefitRestService()] + [BaseAddress()] public interface IRelativePathApi2 { HttpClient Client { get; } diff --git a/Refit/Attributes.cs b/Refit/Attributes.cs index 8389a7972..afcaa7300 100644 --- a/Refit/Attributes.cs +++ b/Refit/Attributes.cs @@ -320,9 +320,9 @@ public QueryAttribute(CollectionFormat collectionFormat) } [AttributeUsage(AttributeTargets.Interface)] - public class RefitRestServiceAttribute : Attribute + public class BaseAddressAttribute : Attribute { - public RefitRestServiceAttribute(string relativePath = null) + public BaseAddressAttribute(string relativePath = null) { RelativePath = relativePath; } diff --git a/Refit/RestService.cs b/Refit/RestService.cs index 012a12e4b..41ef3f2b4 100644 --- a/Refit/RestService.cs +++ b/Refit/RestService.cs @@ -44,7 +44,7 @@ public static object For(Type refitInterfaceType, HttpClient client, IRequestBui { var generatedType = TypeMapping.GetOrAdd(refitInterfaceType, type => GetGeneratedType(type)); - var aps = refitInterfaceType.GetTypeInfo().GetCustomAttributes(true).OfType().FirstOrDefault(); + var aps = refitInterfaceType.GetTypeInfo().GetCustomAttributes(true).OfType().FirstOrDefault(); if (aps != null && !string.IsNullOrEmpty(aps.RelativePath)) {