Skip to content

Dependency Injection and IoC Containers

Christian Findlay edited this page Jul 12, 2020 · 6 revisions

RestClient.Net supports all Dependency Injection frameworks and IoC containers such as Microsoft Dependency Injection which developers commonly use in ASP.Net Core.

The RestClient.Net.Abstractions NuGet package provides base level interfaces and classes. It does not have any further dependencies. The RestClient.Net NuGet package only depends on minimal abstractions and HttpClient assemblies by design. The framework does not tightly couple itself with any external frameworks for things like serialization. Client construction requires a SerializationAdapters to serialize or deserialize content body.

The base interfaces are IClient, and IClientFactory. Simple apps that only need one client throughout the lifespan should depend on IClient. When the app needs multiple clients, the clients should be named, and each class that depends on a client should retrieve the client from the factory instance. Each class that uses a client should accept a factory or client as a constructor argument. When using a factory, the client can be created in the constructor, or on every request. Below is a simple example

public class PersonService
{
  IClient _client;

  public PersonService(IClientFactory clientFactory)
  {
    _client = clientFactory.CreateClient("Person");
  }

  public async Task<Person> SavePerson(Person person)
  {
    return await _client.PostAsync<Person, Person>(person);
  }
}

It allows for Unit Testing with no coupling with the RestClient.Net implementation. This pattern can be used in any application with existing http client code. It is not necessary to use the Client class which depends on Microsoft's HttpClient class.

IoC Containers

This example uses StructureMap as an IoC container.

Code Reference

var container = new Container(c =>
{
    c.Scan(s =>
    {
        s.TheCallingAssembly();
        s.WithDefaultConventions();
    });

    c.For<CreateClient>().Use<CreateClient>(con => new ClientFactory(con.GetInstance<ISerializationAdapter>(), con.GetInstance<CreateHttpClient>(), null).CreateClient);
    c.For<CreateHttpClient>().Use<CreateHttpClient>(con => new DefaultHttpClientFactory().CreateClient);
    c.For<ILogger>().Use<ConsoleLogger>();
    c.For<ISerializationAdapter>().Use<NewtonsoftSerializationAdapter>();
});

var clientFactory = container.GetInstance<CreateClient>();
var client = clientFactory("Test");
Assert.IsNotNull(client);
Assert.AreEqual("Test", client.Name);

This example uses a Microsoft Dependency Injection IoC container.

Code Reference

var serviceCollection = new ServiceCollection();
var baseUri = new Uri("https://restcountries.eu/rest/v2/");
serviceCollection.AddSingleton(typeof(ISerializationAdapter), typeof(NewtonsoftSerializationAdapter));
serviceCollection.AddSingleton(typeof(ILogger), typeof(ConsoleLogger));
serviceCollection.AddSingleton<MockAspController>();
serviceCollection.AddHttpClient("test", (c) => { c.BaseAddress = baseUri; });
serviceCollection.AddDependencyInjectionMapping();
var serviceProvider = serviceCollection.BuildServiceProvider();
var mockAspController = serviceProvider.GetService<MockAspController>();
var response = await mockAspController.Client.GetAsync<List<RestCountry>>();