C# .NET CORE WEB.API — Inject Multiple Instance of some Interface

Eran Hadad
2 min readJan 4, 2021

--

Let’s assume that we’re writing one ISomeService interface and 3 different classes, SomeServiceA, SomeServiceBand SomeServiceC implementing the interface.

public interface ISomeService{string Title { get; }}-=--=--=--=--=--=--=--=--=--=--=--=--=--=-
public class
SomeServiceA: ISomeService
{ public string Title { get { return "A"; } }}
-=--=--=--=--=--=--=--=--=--=--=--=--=--=-
public class
SomeServiceB: ISomeService{
public string Title { get { return "B"; } }}-=--=--=--=--=--=--=--=--=--=--=--=--=--=-
public class
SomeServiceC: ISomeService{
public string Title { get { return "C"; } }}

👎 Instead of registering them like this 👎

public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<ISomeService, SomeServiceA>(); services.AddTransient<ISomeService, SomeServiceB>(); services.AddTransient<ISomeService, SomeServiceC>();
}

😎 We are gonna extend Assembly like this 😎

public static class AssemblyExtension{public static IEnumerable<Type> GetTypesFrom<T>(this Assembly assembly){List<Type> types = new List<Type>();foreach (var type in assembly.DefinedTypes){if (typeof(T).IsAssignableFrom(type) && typeof(T) != type){types.Add(type);}}return types;}}

The main idea is that if in the future we add another class that will implement the ISomeService interface, we will not have to register it in the services 😀

  • typeof(T) != type validate that we “skip” the interface :)
  • From Microsoft —

IsAssignableFrom - Determines whether an instance of a specified type can be assigned to a variable of the current type.

And in the startup we gonna use it like this -

Assembly.GetEntryAssembly().GetTypesFrom<ISomeService>()
.ForEach((t) =>{
services.AddTransient(typeof(ISomeService), t);
});

(the ForEach extension for IEnumerable) —

public static void ForEach<T>(this IEnumerable<T> source, Action<T> action){foreach (T element in source){action(element);}}

In the controller —

private readonly IEnumerable<ISomeService> _services;
.
.
.
[HttpGet][Route(“{serviceType}”)]public IActionResult Get(string serviceType){var concreteService = _services.FirstOrDefault(service => service.Title.ToLower() == serviceType.Trim().ToLower());return Ok($”{concreteService.GetType().Name}”);}
  • [Optional] — we can extract the validation logic of serviceType to ActionFilter Instead of doing it at the Controller (If serviceType is invalid, or empty, etc., etc., etc.)

Good Luck 🤞,

Eran Hadad

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

No responses yet

Write a response