Built-in dependency injection with conventions

I guess you like the way it works with Autofac:

var assembly = typeof(MyModule).Assembly;
builder.RegisterAssemblyTypes(assembly)
    .Where(t => t.Name.EndsWith("Service"))
    .AsImplementedInterfaces()
    .InstancePerLifetimeScope();

But you don't want to switch to Autofac for some reasons (for example you want use extensions from external libraries to register their dependencies). So my suggestion is to create some extensions that use reflection like these ones:

public static IServiceCollection AddSingletonsByConvention(this IServiceCollection services, Assembly assembly, Func<Type, bool> interfacePredicate, Func<Type, bool> implementationPredicate)
{
    var interfaces = assembly.ExportedTypes
        .Where(x => x.IsInterface && interfacePredicate(x))
        .ToList();
    var implementations = assembly.ExportedTypes
        .Where(x => !x.IsInterface && !x.IsAbstract && implementationPredicate(x))
        .ToList();
    foreach (var @interface in interfaces)
    {
        var implementation = implementations.FirstOrDefault(x => @interface.IsAssignableFrom(x));
        if (implementation == null) continue;
        services.AddSingleton(@interface, implementation);
    }
    return services;
}

public static IServiceCollection AddSingletonsByConvention(this IServiceCollection services, Assembly assembly, Func<Type, bool> predicate)
    => services.AddSingletonsByConvention(assembly, predicate, predicate);

Now you can register all your services by simple code like this:

var assembly = typeof(MyType).Assembly;
services.AddSingletonsByConvention(assembly, x => x.Name.EndsWith("Service"));

Feel free to customize these extensions to match your needs. For example you can fire an exception if you don't find implementations for some services if that will make you feel a bit safer.


The out-of-the-box DI doesn't support it and do not intend to do so. The built-in IoC Container is kept simple by design, to allow basic dependency injection which works for most cases.

If you want advanced features like registering by convention, assembly scanning or decorator support, you have to use 3rd party IoC container like Autofac, SimpleInjector, Castle Windsor.