#if !NETSTANDARD1_3
using System.Collections.Generic;
using System.Linq;
using EdjCase.JsonRpc.Router.Abstractions;
using System;
using System.Reflection;
using EdjCase.JsonRpc.Router.MethodProviders;
using Microsoft.Extensions.Options;
namespace EdjCase.JsonRpc.Router.RouteProviders
{
///
/// Default route provider to give the router the configured routes to use
///
public class RpcAutoRouteProvider : IRpcRouteProvider
{
public IOptions Options { get; }
public RpcAutoRouteProvider(IOptions options)
{
this.Options = options ?? throw new ArgumentNullException(nameof(options));
}
public RpcPath BaseRequestPath => this.Options.Value.BaseRequestPath;
private Dictionary> routeCache { get; set; }
private Dictionary> GetAllRoutes()
{
if (this.routeCache == null)
{
//TODO will entry assembly be good enough
List controllerTypes = Assembly.GetEntryAssembly().DefinedTypes
.Where(t => !t.IsAbstract && t.IsSubclassOf(this.Options.Value.BaseControllerType))
.ToList();
var controllerRoutes = new Dictionary>();
foreach (TypeInfo controllerType in controllerTypes)
{
var attribute = controllerType.GetCustomAttribute(true);
string routePathString;
if (attribute == null || attribute.RouteName == null)
{
if (controllerType.Name.EndsWith("Controller"))
{
routePathString = controllerType.Name.Substring(0, controllerType.Name.IndexOf("Controller"));
}
else
{
routePathString = controllerType.Name;
}
}
else
{
routePathString = attribute.RouteName;
}
RpcPath routePath = RpcPath.Parse(routePathString);
if (!controllerRoutes.TryGetValue(routePath, out List methodProviders))
{
methodProviders = new List();
controllerRoutes[routePath] = methodProviders;
}
methodProviders.Add(new ControllerPublicMethodProvider(controllerType.AsType()));
}
this.routeCache = controllerRoutes;
}
return this.routeCache;
}
///
/// Gets all the routes from all the controllers derived from the
/// configured base controller type
///
/// All the available routes
public HashSet GetRoutes()
{
Dictionary> routes = this.GetAllRoutes();
return new HashSet(routes.Keys);
}
///
/// Gets all the method providers for the specified path
///
/// Path to the methods
/// All method providers for the specified path
public List GetMethodsByPath(RpcPath path)
{
Dictionary> routes = this.GetAllRoutes();
if (!routes.TryGetValue(path, out List methods))
{
return new List();
}
return methods;
}
}
}
#endif