Search code examples
c#.netasp.net-corereflectionrazor-pages

Detecting if an assembly contains Razor pages or components


I have a plugin architecture where I use the app.MapRazorComponents<MyApp>().AddAdditionalAssemblies() method to add the plugin assemblies to Razor page mapping.

The plugins are not guaranteed to include any pages so I only want to add assemblies that has files with the @page directive.

I've done some debugging to find that the classes generated for the .razor files have the [Microsoft.AspNetCore.Components.RouteAttribute] set on them, so I guess the @page directive is translated to a [Route] attribute.

The [Route] attribute, however, can also be used on Controllers, which are added differently (.MapControllers()), so only using this attribute as a marker is not enough.

I could probably exclude types that also has the [ApiController] attribute, or add checks for even more attributes (or inheritances), but I feel this can quickly get out of hand.

This is in .NET 8 using the Blazor Web App template with Server render mode.

Is there a way to check if an assembly contains any .razor files (be it pages or components), or alternatively check if an assembly is a "Razor Class Library" or not just a "Class Library"?


Solution

  • This is the same method used to detect razor pages as the AddAdditionalAssemblies method.

    static bool ContainsRazorPagesOrComponents(Assembly assembly)
    {
        var exported = assembly.GetExportedTypes();
    
        for (var i = 0; i < exported.Length; i++)
        {
            var candidate = exported[i];
            if (candidate.IsAssignableTo(typeof(IComponent)))
            {
                if (candidate.GetCustomAttributes<RouteAttribute>() is { } routes &&
                    routes.Any())
                {          
                    return true;
                }
            }
        }
    
        return false;
    }