using Microsoft.Extensions.DependencyInjection;
private static IServiceProvider BuildServices() => new ServiceCollection()
.AddFactory<ISomething, Something>()
var serviceProvider = BuildServices();
var something0 = serviceProvider.GetRequiredService<ISomething>();
var something1 = serviceProvider.Inject<ISomething>();
var something2 = serviceProvider.Inject<ISomething>(something1);
var something3 = serviceProvider.Inject<ISomething>(Guid.NewGuid());
public interface ISomething
void DoSomething() => Console.WriteLine(nameof(DoSomething));
public class Something : ISomething
Console.WriteLine($"{this.GetType()} created");
public Something(Guid context) =>
Console.WriteLine($"{this.GetType()} created with {context.GetType()}");
public Something(ISomething source) =>
Console.WriteLine($"{this.GetType()} created with {source.GetType()}");
public Something(IServiceProvider sp) =>
Console.WriteLine($"{this.GetType()} created with {sp.GetType()}");
public Something(IServiceProvider sp, Guid context) =>
Console.WriteLine($"{this.GetType()} created with {sp.GetType()}, {context.GetType()}");
public Something(IServiceProvider sp, ISomething context) =>
Console.WriteLine($"{this.GetType()} created with {sp.GetType()}, {context.GetType()}");
public static class DependencyInjectionExtensions
public delegate TService Factory<out TService>(IServiceProvider? serviceProvider, params object[] parameters);
public static IServiceCollection AddFactory<TService, TInstance>(this IServiceCollection @this)
where TInstance : class, TService
.AddSingleton<Factory<TService>>(factoryServiceProvider =>
(callerServiceProvider, parameters) =>
ActivatorUtilities.CreateInstance<TInstance>(
callerServiceProvider ?? factoryServiceProvider, parameters))
.AddTransient<TService>(serviceProvider =>
ActivatorUtilities.CreateInstance<TInstance>(serviceProvider, serviceProvider));
public static TService Inject<TService>(this IServiceProvider @this, params object[] parameters)
var factory = @this.GetService<Factory<TService>>();
if (!parameters.Any(p => p is IServiceProvider))
return factory(@this, parameters.Prepend(@this).ToArray());
return factory(@this, parameters);
return @this.GetRequiredService<TService>();