Last active
October 24, 2023 15:31
-
-
Save bennor/c73870e810f8245b2b1d to your computer and use it in GitHub Desktop.
A polyfill for Refit 2.0+ in scripting environments (e.g. LINQPad). Warning: This won't work on all platforms Refit 2.0+ supports (e.g. iOS, maybe WinRT?).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Net.Http; | |
using Castle.DynamicProxy; // From Castle.Core | |
using Refit; | |
public class ProxyRestService | |
{ | |
static readonly ProxyGenerator Generator = new ProxyGenerator(); | |
public static T For<T>(HttpClient client) | |
where T : class | |
{ | |
if(!typeof(T).IsInterface) { | |
throw new InvalidOperationException("T must be an interface."); | |
} | |
var interceptor = new RestMethodInterceptor<T>(client); | |
return Generator.CreateInterfaceProxyWithoutTarget<T>(interceptor); | |
} | |
public static T For<T>(string hostUrl) | |
where T : class | |
{ | |
var client = new HttpClient() { BaseAddress = new Uri(hostUrl) }; | |
return For<T>(client); | |
} | |
class RestMethodInterceptor<T> : IInterceptor | |
{ | |
static readonly Dictionary<string, Func<HttpClient, object[], object>> methodImpls | |
= RequestBuilder.ForType<T>().InterfaceHttpMethods | |
.ToDictionary(k => k, v => RequestBuilder.ForType<T>().BuildRestResultFuncForMethod(v)); | |
readonly HttpClient client; | |
public RestMethodInterceptor(HttpClient client) | |
{ | |
this.client = client; | |
} | |
public void Intercept(IInvocation invocation) | |
{ | |
if (!methodImpls.ContainsKey(invocation.Method.Name)) { | |
throw new NotImplementedException(); | |
} | |
invocation.ReturnValue = methodImpls[invocation.Method.Name](client, invocation.Arguments); | |
} | |
} | |
} |
just use the following to create the dictionary:
static readonly Dictionary<string, Func<HttpClient, object[], object>> methodImpls
= typeof(T).GetMethods().Select(m => m.Name)
.ToDictionary(k => k, v => RequestBuilder.ForType<T>().BuildRestResultFuncForMethod(v));
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@jrotello 100% okay with it (only just saw your comment). But as has been mentioned -- the above code isn't compatible with Refit 4+.