Currently, if an API interface A(HasRefitHttpMethodAttribute) is an aggregation of other interfaces(HasRefitHttpMethodAttribute) then the generated stub for A doesn麓t implement the aggregated interfaces;
using Refit
...
interface InterfaceA : InterfaceB
{
[Get("/ping")]
Task Ping();
}
interface InterfaceB
{
[Get("/ping")]
Task Pong();
}
The generated stub look like this, and doesn麓t obviously compile
using Refit
...
class AutoGeneratedA : InterfaceA
{
...
public Task Ping() { ... }
}
class AutoGeneratedB : InterfaceB
{
...
public Task Pong() { ... }
}
This should/could have been the following
using Refit
...
class AutoGeneratedA : AutoGeneratedB, InterfaceA
{
...
public Task Ping() { ... }
}
class AutoGeneratedB : InterfaceB
{
...
public Task Pong() { ... }
}
I麓m trying to seggregate the interface to better know what client a particular ViewModel(of my MVVM) uses or is supposed to use, i use a IoC container to inject specific implementations.
The registration uses reflection:
using System;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using Refit;
namespace Service.Clients
{
using Core.Common;
using IoC;
public class RestServicesWrapper
{
static RestServicesWrapper()
{
RestServiceType = typeof(RestService);
var parameterTypes = new Type[] { typeof(HttpClient) };
RestServiceFactory = RestServiceType.GetRuntimeMethod("For", parameterTypes);
WebApiClientsAssembly = typeof(RestServicesWrapper).GetTypeInfo().Assembly; ;
}
private static MethodInfo RestServiceFactory { get; set; }
private static Type RestServiceType { get; set; }
private static Assembly WebApiClientsAssembly { get; set; }
public static object For(Type serviceContractType, HttpClient httpClient)
{
return RestServiceFactory
.MakeGenericMethod(serviceContractType)
.Invoke(RestServiceType, new object[] { httpClient });
}
public static void RegisterServices()
{
var httpClient = new HttpClient();
var services =
from service in WebApiClientsAssembly.ExportedTypes
let type = service.GetTypeInfo()
where type.GetCustomAttributes<WebApiContractAttribute>().Any() // A custom marker attribute
select service;
var container = Container.Default;
foreach (var service in services)
container.Register(service, () => For(service, httpClient));
}
}
}
Hi any word on this. at least a "NO WAY"(with why) would be apreciated! @paulcbetts :)
Just for the love your "reactive endeavours"
For me it is an important missing feature too!
Your suggestion could not be used because multiple classes inheritance isn't supported by C#.
Imagine you have :
interface A : B, C
{
[Get("/ping")]
Task Ping();
}
interface B
{
[Get("/pong")]
Task Pong();
}
interface C
{
[Get("/pang")]
Task Pang();
}
Then, this is not valid :
using Refit
...
class A : AutoGeneratedB, AutoGeneratedC, A // <- Not valid !
{
...
public Task Ping() { ... }
}
class AutoGeneratedB : B
{
...
public Task Pong() { ... }
}
class AutoGeneratedC : C
{
...
public Task Pang() { ... }
}
But you could do that at generation, all methods from inherited interfaces could be reflected and regenerated each time by all registered child interfaces.
but this is valid
using Refit
...
class A : AutoGeneratedB, A
{
...
public Task Ping() { ... }
}
class AutoGeneratedB : AutoGeneratedC, B
{
...
public Task Pong() { ... }
}
class AutoGeneratedC : C
{
...
public Task Pang() { ... }
}
//And so is this
using Refit
...
class AutoGeneratedABC : A, B, C
{
...
Task A.Ping() { ... }
...
Task B.Pong() { ... }
...
Task C.Pang() { ... }
}
Yes, I was thinking about this. I'll try to see if I could do a PR for this, maybe @paulcbetts hasn't much time at the moment. :)
Any progress here? This feature would be really a great enhancement. Imagine the possibilities!
This too was just done in #633 - so this can be closed as well 馃槉
Most helpful comment
Yes, I was thinking about this. I'll try to see if I could do a PR for this, maybe @paulcbetts hasn't much time at the moment. :)