1

I want to do the following:

Imagine I have the classes that implement the interface IValidator. I want to find all of those classes and register them in dotnet core standard dependency injection container.

Example:

        services.AddSingleton<IValidator<Delete.Command>, Delete.CommandValidator>();
        services.AddSingleton<IValidator<CreateOrUpdate.Command>, CreateOrUpdate.CommandValidator>();

I know how to find the classes.

var type = typeof(IMyInterface);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p));

The problem is that I don't know how to register them after I find them.

I don't know what keywords to use to search in internet for information. That's why I decided to ask question here.

Thanks!

Dobromir Ivanov
  • 313
  • 4
  • 12
  • Does this answer your question? [How do I use reflection to call a generic method?](https://stackoverflow.com/questions/232535/how-do-i-use-reflection-to-call-a-generic-method) – thehennyy Nov 16 '20 at 17:03
  • hey @thehennyy it is similar to what I am looking yes. Definitely useful link, but I found easier solution that is already build-in in the dotnet framework. I posted it as an answer below. – Dobromir Ivanov Nov 16 '20 at 17:12

2 Answers2

1

I found it, it looks like the .NET methods accept types. You can delete my question or leave it for people that are stuck with the same question.

var interfaceType = typeof(IValidator<Delete.Command>);
var implementationType = typeof(Delete.CommandValidator);
services.AddSingleton(interfaceType, implementationType);
Dharman
  • 30,962
  • 25
  • 85
  • 135
Dobromir Ivanov
  • 313
  • 4
  • 12
0

Which IoC container are you using? You should always specify this when asking a question since each IoC container might have different methods, for instance if you are using Autofac there's a dedicated method RegisterAssemblyTypes that doesn't require you to scan the assemblies manually. Anyhow, following your example something like this should works:

foreach (var type in types)
{
    foreach (var iType in type.GetInterfaces())
    {
        services.AddSingleton(iType, type);
    }
}

Another option could be create the instance for each type and then register it:

var instances = types.Select(t => (IIMyInterface)Activator.CreateInstance(t)).ToList();
foreach(var instance in instances)
     services.AddSingleton<IIMyInterface>(instance); 

Let me know if it works (It's not clear to me how's the implementation of Delete.CommandValidator and CreateOrUpdate.CommandValidator)

BTW be careful with GetAssemblies as it returns only the loaded assemblies. If you need to get Assemblies from different project (with nested references) you should load assemblies directly from the dll. If this is the case then check this out: https://github.com/nopSolutions/nopCommerce/blob/develop/src/Libraries/Nop.Core/Infrastructure/AppDomainTypeFinder.cs

  • Thank you for the detailed explanation. Currently I am using the build-in dependency injection in dotnet core. I don't know its name that's why I didn't mentioned it. Later on we might move to Autofac. So both your suggestions will be useful for me. – Dobromir Ivanov Nov 16 '20 at 18:12
  • Cool! Autofac is a really mature IoC container and it has a lof of functionalities that are missing in other containers. BTW if you think my answer was useful, please vote it :)...Thanks a lot! – Simone Pozzobon Nov 16 '20 at 18:22
  • hey Simone, I voted for your answer, but because I don't have enough reputation my vote is recorded, but not yet counted. – Dobromir Ivanov Nov 16 '20 at 22:40