Lord of Scripts
Lord of Scripts

Reputation: 3619

Get types implementing interface in ASP.NET Core web application

I am trying to port some of my plain ASP.NET (MVC) code to the ASP.NET Core web application. My code looked like this:

    System.Web.Compilation.BuildManager.GetReferencedAssemblies()
       .Cast<System.Reflection.Assembly>()
       .SelectMany(
           a => a.GetTypes()).Where(type => typeof(IGoogleSitemap).IsAssignableFrom(type)
        )
        .ToList(); 

But I am not getting that to work on ASP.NET Core (1.1). For one thing Assembly does not have GetReferencedAssemblies() only GetEntryAssembly(). And GetEntryAssembly().GetReferencedAssemblies() gives me a list of AssemblyName instead of Assembly objects.

Basically I am looking for all controllers implementing the IGoogleSitemap interface (defined in a separate assembly).

Upvotes: 2

Views: 898

Answers (2)

undefined
undefined

Reputation: 2989

I found a (terribly inefficient) 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.

Upvotes: 0

Lord of Scripts
Lord of Scripts

Reputation: 3619

As I mentioned, .NET Core being so streamlined causes some things to be more complicated. I got it to work by changing the code to this (.NET Core 1.1)

IEnumerable<System.Reflection.TypeInfo> all = 
        Assembly.GetEntryAssembly().DefinedTypes.Where(type => 
              typeof(FullNamespace.IGoogleSitemap).IsAssignableFrom(type.AsType()));
 foreach (TypeInfo ti in all)
 {
     Type t = ti.AsType();
     // of all candidates filter out the actual interface definition
     if (!t.Equals(typeof(IGoogleSitemap)))
     {
            // do work here
     }
 }

Well, that does it for the Entry Assembly at least, still have not figured out how to do it for all referenced assemblies because GetReferencedAssemblies() returns AssemblyName rather than Assembly.

Upvotes: 1

Related Questions