8000 Add MethodInfo property by donnytian · Pull Request #1219 · reactiveui/refit · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Add MethodInfo property #1219

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,7 @@ Because Refit supports `HttpClientFactory` it is possible to configure Polly pol
If your policy makes use of `Polly.Context` this can be passed via Refit by adding `[Property("PollyExecutionContext")] Polly.Context context`
as behind the scenes `Polly.Context` is simply stored in `HttpRequestMessage.Properties` under the key `PollyExecutionContext` and is of type `Polly.Context`

#### Target Interface Type
#### Target Interface Type and MethodInfo

There may be times when you want to know what the target interface type is of the Refit instance. An example is where you
have a derived interface that implements a common base like this:
Expand All @@ -807,8 +807,9 @@ public interface IOrdersAPI : IGetAPI<Order>
{
}
```

You can access the concrete type of the interface for use in a handler, such as to alter the URL of the request:
You may want to know the information of the current method as well. Then you can add path or tag for metrics and telemetry.
Even more that you may want to set custom attributes to the method.
You can access the concrete type of the interface and the current method for use in a handler, such as to alter the URL of the request:

[//]: # ({% raw %})
```csharp
Expand All @@ -819,7 +820,12 @@ class RequestPropertyHandler : DelegatingHandler
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// Get the type of the target interface
Type interfaceType = (Type)request.Properties[HttpMessageRequestOptions.InterfaceType];
var interfaceType = (Type)request.Properties[HttpMessageRequestOptions.InterfaceType];

// Get the methodInfo of the current method
var methodInfo = (MethodInfo)request.Properties[HttpMessageRequestOptions.MethodInfo];

// do something with methodInfo with method name, custom attributes and etc.

var builder = new UriBuilder(request.RequestUri);
// Alter the Path in some way based on the interface or an attribute on it
Expand Down
4 changes: 2 additions & 2 deletions Refit.Tests/MultipartTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -308,12 +308,12 @@ public async Task MultipartUploadShouldWorkWithHeaderAndRequestProperty()
Assert.Equal(someHeader, message.Headers.Authorization.ToString());

#if NET5_0_OR_GREATER
Assert.Equal(2, message.Options.Count());
Assert.Equal(3, message.Options.Count());
Assert.Equal(someProperty, ((IDictionary<string, object>)message.Options)["SomeProperty"]);
#endif

#pragma warning disable CS0618 // Type or member is obsolete
Assert.Equal(2, message.Properties.Count);
Assert.Equal(3, message.Properties.Count);
Assert.Equal(someProperty, message.Properties["SomeProperty"]);
#pragma warning restore CS0618 // Type or member is obsolete
},
Expand Down
24 changes: 22 additions & 2 deletions Refit.Tests/RequestBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2141,6 +2141,26 @@ public void InterfaceTypeShouldBeInProperties()

}

[Fact]
public void MethodInfoShouldBeInProperties()
{
var fixture = new RequestBuilderImplementation<IContainAandB>();
var factory = fixture.BuildRequestFactoryForMethod(nameof(IContainAandB.Ping));
var output = factory(new object[] { });

#if NET5_0_OR_GREATER
Assert.NotEmpty(output.Options);
Assert.Equal(typeof(IAmInterfaceA).GetMethod(nameof(IAmInterfaceA.Ping)),
((IDictionary<string, object>)output.Options)[HttpRequestMessageOptions.MethodInfo]);
#endif

#pragma warning disable CS0618 // Type or member is obsolete
Assert.NotEmpty(output.Properties);
Assert.Equal(typeof(IAmInterfaceA).GetMethod(nameof(IAmInterfaceA.Ping)),
output.Properties[HttpRequestMessageOptions.MethodInfo]);
#pragma warning restore CS0618 // Type or member is obsolete
}

[Fact]
public void DynamicRequestPropertiesWithDefaultKeysShouldBeInProperties()
{
Expand Down Expand Up @@ -2174,12 +2194,12 @@ public void DynamicRequestPropertiesWithDuplicateKeyShouldOverwritePreviousPrope


#if NET5_0_OR_GREATER
Assert.Equal(2, output.Options.Count());
Assert.Equal(3, output.Options.Count());
Assert.Equal(someOtherProperty, ((IDictionary<string, object>)output.Options)["SomeProperty"]);
#endif

#pragma warning disable CS0618 // Type or member is obsolete
Assert.Equal(2, output.Properties.Count);
Assert.Equal(3, output.Properties.Count);
Assert.Equal(someOtherProperty, output.Properties["SomeProperty"]);
#pragma warning restore CS0618 // Type or member is obsolete
}
Expand Down
13 changes: 7 additions & 6 deletions Refit/HttpRequestMessageProperties.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Refit
{
Expand All @@ -12,8 +8,13 @@ namespace Refit
public static class HttpRequestMessageOptions
{
/// <summary>
/// Returns the <see cref="System.Type"/> of the top-level interface where the method was called from
/// Returns the <see cref="Type"/> of the top-level interface where the method was called from.
/// </summary>
public static string InterfaceType { get; } = "Refit.InterfaceType";
public static string InterfaceType => "Refit.InterfaceType";

/// <summary>
/// Returns the <see cref="System.Reflection.MethodInfo"/> of the executing method.
/// </summary>
public static string MethodInfo => "Refit.MethodInfo";
}
}
6 changes: 3 additions & 3 deletions Refit/RequestBuilderImplementation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -733,15 +733,15 @@ Func<object[], HttpRequestMessage> BuildRequestFactoryForMethod(RestMethodInfo r
#endif
}

// Always add the top-level type of the interface to the properties
// Always add the top-level type of the interface and the current method to the properties
#if NET5_0_OR_GREATER
ret.Options.Set(new HttpRequestOptionsKey<Type>(HttpRequestMessageOptions.InterfaceType), TargetType);
ret.Options.Set(new HttpRequestOptionsKey<MethodInfo>(HttpRequestMessageOptions.MethodInfo), restMethod.MethodInfo);
#else
ret.Properties[HttpRequestMessageOptions.InterfaceType] = TargetType;
ret.Properties[HttpRequestMessageOptions.MethodInfo] = restMethod.MethodInfo;
#endif

;

// NB: The URI methods in .NET are dumb. Also, we do this
// UriBuilder business so that we preserve any hardcoded query
// parameters as well as add the parameterized ones.
Expand Down
0