How to allow for optional services with Microsoft.Extension.DependencyInjection?

By their very nature, constructor injection is always considered as mandatory.

The very first versions of the Microsoft DI (I don't like using the term ASP.NET Core DI, because it does not depend on ASP.NET Core and can be used outside of it) only supported the constructor with the most parameters.

I think this has been changed since then to allow multiple constructors and the IoC container will choose a fitting one. That being said, you'd likely need to define multiple constructors.

public IServiceManager(IService service, IOtherService otherService)
{
}

public IServiceManager(IOtherService otherService)
{
}

Then the second constructor should be called, if IService isn't registered with the IoC container.

But it's still quite a questionable practice at best and makes your code harder to maintain and hold its invariant/loose coupling.

You should never have to instantiate your types inside your services, not even for optional services.

Instead, you should provide registrations which allow a user to override them with their own implementations.

public static IServiceCollection AddMyLibrary(this IServiceCollection services)
{
    services.TryAddTransient<IService, Service>();
    services.TryAddTransient<IOtherService, OtherService>();
}

Then the user override it.

services.AddTransient<IService, CustomService>();
services.AddMyLibrary();

Now CustomService will be injected where IService is requested.


Add default value to that parameter in the constructor.

public IServiceManager(IService service = null, ...)
{
  _service = service ?? new DefaultService();
  ...
}