Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET Core IoC RegisterAssemblyTypes Equivalant

I am using the built in .NET Core IoC container. But I need functionality similar to that which comes with AutoFac. I want to limit the amount of third-party dependencies in this project. So I was hoping I could do something similar to the following AutoFac method in the .NET Core IoC container:

builder.RegisterAssemblyTypes(assemblyhere).AsImplementedInterfaces();

Is this possible?

like image 546
YodasMyDad Avatar asked Mar 03 '17 06:03

YodasMyDad


People also ask

What is .NET Core IoC?

ASP.NET Core supports the dependency injection (DI) software design pattern, which is a technique for achieving Inversion of Control (IoC) between classes and their dependencies. For more information specific to dependency injection within MVC controllers, see Dependency injection into controllers in ASP.NET Core.

What is built in IoC container in .NET Core?

ASP.NET Core framework includes built-in IoC container for automatic dependency injection. The built-in IoC container is a simple yet effective container.

What is Scrutor?

Scrutor - I search or examine thoroughly; I probe, investigate or scrutinize. From scrūta, as the original sense of the verb was to search through trash. - https://en.wiktionary.org/wiki/scrutor. Assembly scanning and decoration extensions for Microsoft.Extensions.DependencyInjection.


3 Answers

Yes you can do it with the built-in .NET Core IOC container, using Scrutor extension methods. It has got some nice assembly scanning functionalities.

Try this:

services.Scan(scan => scan
                .FromAssemblies(typeof(yourassembly).GetTypeInfo().Assembly)
                .AddClasses()
                .AsImplementedInterfaces()
                .WithScopedLifetime());

It applies on the built-in IOC container, though it's not itself a built-in package (Scrutor package on Nuget):

like image 105
Pierre Murasso Avatar answered Oct 28 '22 14:10

Pierre Murasso


You can easily implement your own method to register all assembly types for a given assembly or set of assemblies... the code would be along the lines of:

foreach (var implementationType in assemblies.SelectMany(assembly => assembly.GetTypes()).Where(type => !type.GetTypeInfo().IsAbstract))
{
    foreach(var interfaceType in implementationType.GetInterfaces())
    {
        services.AddSingleton(interfaceType, implementationType);
    }
}

The code selects all non-abstract types from assemblies and retrieves all interfaces for each type creating a Singleton registration for each interface/implementation pair.


I prefer to register all instances of an explicit interface (i.e., ICommandHandler or similar), so I add extension methods along the lines of AddCommandHandlers shown below for the few types I want any instance of to be registered...

public static void AddCommandHandlers(this IServiceCollection services, params Assembly[] assemblies)
{
    var serviceType = typeof(ICommandHandler);

    foreach (var implementationType in assemblies.SelectMany(assembly => assembly.GetTypes()).Where(type => serviceType.IsAssignableFrom(type) && !type.GetTypeInfo().IsAbstract))
    {
        services.AddSingleton(serviceType, implementationType);
    }
}

Adding a call similar to services.AddCommandHandlers(DomainAssembly.Reference); in ConfigureServices...

I prefer this approach, because registering all interfaces for all types will add a lot of cruft registrations to your IoC container... typically not a huge deal, but cleaner in my opinion.

like image 3
Chris Baxter Avatar answered Oct 28 '22 13:10

Chris Baxter


I can offer my assembly for type binding Nuget Q101.ServiceCollectionExtensions maybe it will be convenient to use.

            services.RegisterAssemblyTypes(typeof(ITypeInterface).Assembly)
            .Where(t => t.Name.EndsWith("EndNameOfType") 
                    && t.GetInterfaces()
                        .Any(ti => ti.Name == typeof(ITypeInterface).Name))
            .AsScoped()    // Similarly Like As services.AddScoped(T1, T2)
            .PropertiesAutowired() // Set properties values                
            .Bind();        
...
        services.RegisterAssemblyTypesByName(typeof(IStudentRepository).Assembly,
            name => name.EndsWith("Repository")) // Condition for name of type
            .AsScoped()    // Similarly Like As services.AddScoped(T1, T2)
            // Set binding like as services.AddScoped<IRepository, Repository>();
            .AsImplementedInterfaces()                 
            .Bind();

there is a small instruction manual on the github repository https://github.com/Axelweaver/q101-net-core22-service-collection-extensions

like image 1
Axel Weaver Avatar answered Oct 28 '22 14:10

Axel Weaver