This project simulates the Ninject's ToFactory functionality
but on IServiceCollection.
Types.cs
public interface IBar
{
void DoSomething();
}
public class Bar : IBar
{
public void DoSomething()
=> Console.WriteLine("It works!!!");
}
// Let's add implementation of IBarFactory dynamically!
public interface IBarFactory
{
IBar Factory();
}Program.cs
using Microsoft.Extensions.DependencyInjection;
public static class Program
{
static void Main()
{
ServiceCollection sc = new ServiceCollection();
sc.AddTransient<IBar, Bar>();
// dynamic factory service lifetime
// is singleton by default and can be changed
sc.AddFactory<IBarFactory>();
var sp = sc.BuildServiceProvider();
var barFactory = sp.GetRequiredService<IBarFactory>();
IBar bar = barFactory.Factory();
// outputs 'It works!!!!'
bar.DoSomething();
}
}Magic. (System.Reflection.Emit)
The AddFactory method scans for implementations of the
Factory method return types inside the assembly of
the factory interface type.
E.g. from the example above, the AddFactory will look
for implementations of IBar inside the assembly with
IBarFactory.
It is possible to change that behvaiour and specify which assemblies to scan.
sc.AddFactory<IBarFactory>(params Assembly[] assemblies)AddFactory supports automatic injection of other services
inside the dynamically created factory and then feeding those
services to the newly factored services.
Note that the dependent services must come after any simple types (ints/longs/other num types, enums, structs, strings).
Example:
publi
public interface ISomeDependency { }
public interface IBar1 { }
public class Bar1 : IBar1
{
private int someParameter;
private ISomeDependency someDependency;
// ISomeDependency will be automatically fed by
// the dynamic factory
public Bar1(int someParameter, ISomeDependency someDependency)
{
this.someParameter = someParameter;
this.someDependency = someDependency;
}
public void DoSomething()
{
Console.WriteLine("It works!!!");
}
}
public interface IBar1Factory
{
// dynamic factory will inject ISomeDependency
// and then invoke the ctor with int
IBar1 Factory(int someParameter);
}- The project searches only for methods named
Factoryinside the factory interface. - The return type of the
Factorymethod must be an interface AddFactorywill throw an exception if there are multiple constructors matching the factory method signature.