Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Core Find All Class Types In All Assemblies

I am trying to make a modular based .NET core app, and I need to find all classes of a specific type(s) across all assemblies. As each module will be built in it's own project.

But I can't see/find how to do that in ASP.NET Core? Any pointers would be appreciated.

like image 825
YodasMyDad Avatar asked Mar 01 '17 06:03

YodasMyDad


3 Answers

To load all classes from one assembly please see below code. In My case IProfile is the interface which I need to Search

var all = Assembly
        .GetEntryAssembly()
        .GetReferencedAssemblies()
        .Select(Assembly.Load)
        .SelectMany(x => x.DefinedTypes)
        .Where(type => typeof(IProfile).IsAssignableFrom(type));    

foreach (var ti in all)
{
   var t = ti.AsType();
   if (t.Equals(typeof(IProfile)))
   {

   }
}

Hi leen3o, In case you have external assemblies or Plugins, You can get all types by iterating from the list of assemblies. In below code "GlobalConfiguration.Modules" holds my list of plugins

List<Type> typeToRegisters = new List<Type>();  
    foreach (var module in GlobalConfiguration.Modules)
    {
    typeToRegisters.AddRange(module.Assembly.DefinedTypes.Select(t => t.AsType()));
          }     

    var entity-types = typeToRegisters.Where(x =>  x.GetTypeInfo().IsSubclassOf(typeof(IBaseDomainEntity)) &&  !x.GetTypeInfo().IsAbstract);

here "IBaseDomainEntity" is my Interface I am searching for. The Only thing I am concerned here is the Efficiency that I have not checked

like image 77
Aamir Avatar answered Nov 15 '22 20:11

Aamir


I probably found a way of achieving this,

var all =
        Assembly
        .GetEntryAssembly()
        .GetReferencedAssemblies()
        .Select(Assembly.Load)
        .SelectMany(x => x.DefinedTypes)
        .Where(type => typeof(ICloudProvider).IsAssignableFrom(type.AsType()));
foreach (var ti in all)
{
    var t = ti.AsType();
    if (!t.Equals(typeof(ICloudProvider)))
    {
        // do work
    }
}

I am worried about the cost of the Assembly.Load part, but this will probably get my work done for now - as I only need the Fully Qualified Name of all the classes that implements ICloudProvider.

like image 43
undefined Avatar answered Nov 15 '22 21:11

undefined


I think you should get a collection of all the assemblies you want to search, than you can loop through the assemblies to find a possible type match.

The code below shows you how to get an assignable type. You can also add checks to exclude abstract classes or check if a type implements a generic type.

foreach (var assembly in _assemblies)
{
    foreach (var candidate in assembly.ExportedTypes.Select(t => t.GetTypeInfo()))
    {
        if (assignTypeFrom.GetTypeInfo().IsAssignableFrom(candidate) && candidate.IsClass)
        {
            yield return candidate.AsType();
        }
    }
}
like image 2
user1336 Avatar answered Nov 15 '22 21:11

user1336