Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Register all implementation of type T interface in .NET core

I have an interface

public interface IEvent { }

An Event class

public class ContactEvent : IEvent { }

Two Event Handlers classes

public class ContactCreateHandler : IEventHandler<ContactEvent> { }
public class ContactUpdateHandler : IEventHandler<ContactEvent> { }

In .NET 4.5 this was possible using Autofac

var assemblies = BuildManager.GetReferencedAssemblies()
            .Cast<Assembly>()
            .ToArray()

builder.RegisterAssemblyTypes(assemblies)
.AsClosedTypesOf(typeof(IEventHandler<>)).AsImplementedInterfaces().InstancePerRequest();

And then I would get the list of classes based on the type T

var handlerList = _container.Resolve<IEnumerable<IEventHandler<T>>>();

How to do this in .NET Core

like image 472
hendrixchord Avatar asked Jan 23 '17 12:01

hendrixchord


People also ask

How do I register a class in .NET core?

For registering the interface and classes, you need to go in the Program class (As Startup class is no more with . NET 6) and use these methods i.e "AddScoped" || "AddTransient" || "AddSingleton" as it defines the lifetime of the services. STEP 5 - Go to Program class and register it.

What is IServiceCollection in .NET core?

AddScoped(IServiceCollection, Type, Type) Adds a scoped service of the type specified in serviceType with an implementation of the type specified in implementationType to the specified IServiceCollection.

How do you declare a generic interface?

You can declare variant generic interfaces by using the in and out keywords for generic type parameters. ref , in , and out parameters in C# cannot be variant. Value types also do not support variance. You can declare a generic type parameter covariant by using the out keyword.


1 Answers

You could use Scrutor. With that, you can then scan and assign the handlers like this:

// Automatically discover and register all message handlers...
services.Scan(
    x =>
        {
            var entryAssembly = Assembly.GetEntryAssembly();
            var referencedAssemblies = entryAssembly.GetReferencedAssemblies().Select(Assembly.Load);
            var assemblies = new List<Assembly> { entryAssembly }.Concat(referencedAssemblies);

            x.FromAssemblies(assemblies)
                .AddClasses(classes => classes.AssignableTo(typeof(IEventHandler<>)))
                    .AsImplementedInterfaces()
                    .WithScopedLifetime();
        });
like image 169
Justin Saraceno Avatar answered Nov 14 '22 03:11

Justin Saraceno