ControllerDiscoveryService - mojtabanabavi/Loby.AspNetCore GitHub Wiki

About

A discovery service that provide some information about all controllers and actions. These informations could be used for permission-based authorization and etc.

Namespace

Loby.AspNetCore.Services

Registering service

At first, you should register controller discovery service in your app's service collection at Startup class. Registering can be manually or by using the predefined extension method in Loby.AspNetCore.Extensions.DependencyInjection namespace. Since the features of controllers and it's actions like name, route, etc. are not changing while program is running, it is highly recommended to use the Singleton lifetime.


namespace MyWebApp
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            // manually 
            services.AddSingleton<IControllerDiscoveryService, ControllerDiscoveryService>();

            // using predefined extension method
            services.AddControllerDiscoveryService();

            ...
        }

        ...
    }
}

Properties

The Controllers contains information about all controllers and action methods, and SecuredControllers is like Controllers, but for those that are directly or inheritancely secured using the Microsoft.AspNetCore.Authorization.AuthorizeAttribute attribute.


// A list of all controllers and action methods.
public ICollection<ControllerInfo> Controllers { get; }

// A list of all secured controllers and action methods.
public ICollection<ControllerInfo> SecuredControllers { get; }

ControllerInfo

The ControllerInfo contains the following properties:

Name Type Description
Id string The id of current controller that generated by combination of area name and controller name. Pattern: AreaName:ControllerName
Name string The actual name of controller.
DisplayName string The display name of controller. Display name could be provided by using System.ComponentModel.DisplayNameAttribute.
AreaName string The name of area containing current controller. Area name could be provided by using Microsoft.AspNetCore.Mvc.AreaAttribute.
IsSecured bool A flag that specifies the current controller is protected or not. Protection could be provided by using Microsoft.AspNetCore.Authorization.AuthorizeAttribute.
Attributes IList<System.Attribute> A list that contains all the custom attributes applied to the current controller.
Actions IList<ControllerActionInfo> A list of all actions defined in the current controller.

ControllerActionInfo

The ControllerActionInfo contains the following properties:

Name Type Description
Id string The id of current action that generated by combination of area name, controller name and action name. Pattern: AreaName:ControllerName:ActionName
ControllerId string The id of controller that the current action is defined in it. For more information see ControllerInfo.Id.
Name string The actual name of action.
DisplayName string The display name of action. Display name could be provided by using System.ComponentModel.DisplayNameAttribute.
IsSecured bool A flag that specifies the current action is protected or not. Protection could be provided by using Microsoft.AspNetCore.Authorization.AuthorizeAttribute.
Attributes IList<System.Attribute> A list that contains all the custom attributes applied to the current action.

Methods

Name Parameters output Description
GetSecuredControllers string: policyName IReadOnlyList Get all controllers and actions secured by AuthorizeAttribute and have the specified policyName.

Usage

The controller discovery service can be used by injecting it to your controllers, views or everywhere you need it. The following samples are simple and you can modify them based on your need.

How to use in controllers


public class HomeController : Controller
{
    private readonly IControllerDiscoveryService _controllerDiscoveryService;

    public HomeController(IControllerDiscoveryService controllerDiscoveryService)
    {
        _controllerDiscoveryService = controllerDiscoveryService;
    }

    public IActionResult Index()
    {
        var allControllers = _controllerDiscoveryService.Controllers;

        var allSecuredControllers = _controllerDiscoveryService.SecuredControllers;

        var allSecuredControllersWithPolicy = _controllerDiscoveryService.GetSecuredControllers(policyName: "PolicyName");

        ...
    }
}

How to use in views


@inject Loby.AspNetCore.Services.IControllerDiscoveryService controllerDiscoveryService

@foreach(var controller in controllerDiscoveryService.Controllers)
{
    <p>@controller.DisplayName</p>

    ...

    @foreach(var action in controller.Actions)
    {
        <p>@action.DisplayName</p>

        ...
    }
}

Extending

This service is open to extend. you can easily write your own extension methods that satisfy your need.

For example you can write an extension to filter controllers and actions on area name.


public static class ControllerDiscoveryServiceExtensions
{
    public static IEnumerable<ControllerInfo> GetControllersByArea(this IControllerDiscoveryService controllerDiscoveryService, string areaName)
    {
        var result = controllerDiscoveryService.Controllers.Where(x=> x.AreaName == areaName);

        return result;
    }
}