5.2Interface Definition and Usage
Before using HTTP Declarative Requests, you need to define an interface and make sure it implements the IHttpDeclarative interface:
public interface IHttpService : IHttpDeclarative{}Then, in the Startup.cs or Program.cs file, configure and register the HttpRemote service to enable the HTTP Declarative Requests feature:
services.AddHttpRemote(builder =>{ // Register the IHttpService declarative interface using the generic approach builder.AddHttpDeclarative<IHttpService>(); // Or use the type-based approach // builder.AddHttpDeclarative(typeof(IHttpService)); // To register multiple interfaces, use the following method (not the array syntax shown in this example) // builder.AddHttpDeclaratives(new[] { typeof(IHttpService), typeof(IHttpService) }); // Recommended: scan and batch-register from assemblies // builder.AddHttpDeclarativesFromAssemblies([Assembly.GetEntryAssembly()]); // If using the Furion framework, pass App.Assemblies directly // builder.AddHttpDeclarativesFromAssemblies(App.Assemblies);});When using the IHttpService declarative request in a service, you can inject it through the constructor:
public class YourService{ private readonly IHttpService _httpService; public YourService(IHttpService httpService) { _httpService = httpService; }}If you are using .NET 8 or later, you can use primary constructors injection to further simplify the code:
public class YourService(IHttpService httpService){ // Use the httpService variable}In some scenarios, you can also inject only in a specific method by adding the [FromServices] attribute in front of the parameter:
public class YourService{ public Task<string> GetResource([FromServices] IHttpService httpService) { // Your business logic }}In addition, if you want to dynamically resolve the declarative service, you can first inject IHttpRemoteService and then call its For<T>() method to obtain an instance:
public class YourService(IHttpRemoteService httpRemoteService){ public async Task InvokeAsync() { var httpService = httpRemoteService.For<IHttpService>(); }}Open Generic Interfaces
HTTP declarative interfaces also support open generic definitions, for example:
public interface IHttpService<T> : IHttpDeclarative{}Note that when using the assembly scanning approach (such as builder.AddHttpDeclarativesFromAssemblies(assemblies)), open generic interfaces are skipped by default, because it requires a concrete type at runtime (that is, a closed generic type). In this case, you should explicitly register the closed generic version:
services.AddHttpRemote(builder =>{ // Register a closed generic type, such as IHttpService<string> builder.AddHttpDeclarative<IHttpService<string>>(); // Or use the type-based approach // builder.AddHttpDeclarative(typeof(IHttpService<string>));});When using it in business logic, you can obtain the specified closed type (such as IHttpService<string>) directly through dependency injection, or call IHttpRemoteService.For<IHttpService<string>>() to dynamically resolve the service instance.
No Need to Implement the IHttpDeclarative Interface
In some cases, you may want to generate a declarative proxy directly for an ordinary interface without requiring that interface to implement IHttpDeclarative. For example, define an ordinary IMyApi interface:
public interface IMyApi{ [Get("https://api.furion.net/users/{id}")] Task<User> GetUserAsync(int id);}In this case, specify requireIHttpDeclarative: false when registering:
services.AddHttpRemote(builder =>{ builder.AddHttpDeclarative(typeof(IMyApi), requireIHttpDeclarative: false);});After registration, this interface is used in exactly the same way as an ordinary declarative interface: it can be injected through the constructor, injected with the [FromServices] attribute, or dynamically resolved with IHttpRemoteService.For<T>().