DEV Community

Sam Ferree
Sam Ferree

Posted on

3

Explicit Registration in ASP.NET Core DI

Sometimes you'll want a little more control over how your objects are composed than the IServiceCollection API gives you. You can always fall back to explicit registration.

The AddTransient/Scoped/Singleton methods all have an overload that takes a Func as a factory method to use when an instance is needed.

When is this useful? let's say you have the following objects

public interface IPing
{
  void Ping(string msg);
}

public class ConsolePing : IPing
{
  public void Ping(string msg) =>
    Console.WriteLine(msg);
}

public class LogPing : IPing
{
  public void Ping(string msg) =>
    Log.Info(msg);
}
Enter fullscreen mode Exit fullscreen mode

So you have to different implementations of IPing, then for different services you wanted to inject different implementations, but still only take a dependency on the interface for test mocking.

public class ServiceA
{
  private readonly IPing _pinger;
  public ServiceA(IPing pinger) => _pinger = pinger;
}

public class ServiceB
{
  private readonly IPing _pinger;
  public ServiceB(IPing pinger) => _pinger = pinger;
}
Enter fullscreen mode Exit fullscreen mode

How do you register ServiceA and ServiceB so that A gets the ConsolePinger, and B gets the LogPinger? Use the overload registration that takes in a factory method.

The factory method needs to return an instance of the service you are registering, but it takes as a parameter a service provider that can be used to obtain any dependencies.

public void ConfigureService(IServiceCollection services)
{
  services.AddTransient<ConsolePing>();
  services.AddTransient<LogPing>();
  services.AddTransient<ServiceA>(provider =>
  {
    var consolePinger = provider.GetRequiredService<ConsolePing>();
    return new ServiceA(consolePinger);
  });

  // if you can also omit the generic parameter
  services.AddTransient(provider =>
  {
    var logPinger = provider.GetRequiredService<LogPing>();
    return new ServiceB(logPinger);
  });
}
Enter fullscreen mode Exit fullscreen mode

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay