Files
mixtape/zero.Core/Routing/Routes.cs
T

194 lines
5.3 KiB
C#
Raw Normal View History

using Microsoft.Extensions.Logging;
2020-10-26 13:59:46 +01:00
using Raven.Client.Documents.Linq;
2020-10-23 15:50:59 +02:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
2020-11-15 17:07:27 +01:00
using zero.Core.Database;
2020-10-23 15:50:59 +02:00
using zero.Core.Entities;
2021-11-06 16:27:04 +01:00
2020-10-23 15:50:59 +02:00
namespace zero.Core.Routing
{
public class Routes : IRoutes
{
2021-02-23 15:50:33 +01:00
public const char PATH_SEPERATOR = '/';
2021-11-06 16:27:04 +01:00
protected IZeroContext Context { get; set; }
2021-10-28 12:11:07 +02:00
protected IZeroStore Store { get; set; }
2020-10-23 15:50:59 +02:00
protected ILogger<Routes> Logger { get; set; }
protected IEnumerable<IRouteProvider> Providers { get; set; }
2021-11-06 16:27:04 +01:00
public Routes(IZeroContext context, IZeroStore store, ILogger<Routes> logger, IEnumerable<IRouteProvider> providers)
2020-10-23 15:50:59 +02:00
{
2021-11-06 16:27:04 +01:00
Context = context;
2021-10-28 12:11:07 +02:00
Store = store;
2020-10-23 15:50:59 +02:00
Logger = logger;
Providers = providers;
}
/// <inheritdoc />
2021-11-07 13:51:45 +01:00
public async Task<string> GetUrl<T>(T model) where T : IZeroRouteEntity => (await GetRoute(model))?.Url;
2020-10-23 15:50:59 +02:00
2021-02-10 14:53:56 +01:00
/// <inheritdoc />
2021-11-07 13:51:45 +01:00
public async Task<string> GetUrl<T>(string id) where T : IZeroRouteEntity => (await GetRoute<T>(id))?.Url;
2021-02-10 14:53:56 +01:00
2020-10-23 15:50:59 +02:00
/// <inheritdoc />
2021-11-07 13:51:45 +01:00
public async Task<Dictionary<T, string>> GetUrls<T>(params T[] models) where T : IZeroRouteEntity => (await GetRoutes(models)).ToDictionary(x => x.Key, x => x.Value?.Url);
2020-10-23 15:50:59 +02:00
2021-02-10 14:53:56 +01:00
/// <inheritdoc />
2021-11-07 13:51:45 +01:00
public async Task<Route> GetRoute<T>(string id) where T : IZeroRouteEntity
2021-02-10 14:53:56 +01:00
{
2021-11-07 13:51:45 +01:00
T model = await GetContext().Session.LoadAsync<T>(id);
return await GetRoute(model);
2021-02-10 14:53:56 +01:00
}
2020-10-23 15:50:59 +02:00
/// <inheritdoc />
2021-11-07 13:51:45 +01:00
public async Task<Route> GetRoute<T>(T model) where T : IZeroRouteEntity
2020-10-23 15:50:59 +02:00
{
2021-02-08 15:45:25 +01:00
if (model == null)
{
return null;
}
2021-11-06 16:27:04 +01:00
if (!TryGetProvider(model, out IRouteProvider routeProvider))
2020-10-23 15:50:59 +02:00
{
return null;
}
2021-11-06 16:27:04 +01:00
RoutingContext context = GetContext();
return await FindRoute(routeProvider, context, model);
2020-11-07 14:32:46 +01:00
}
/// <inheritdoc />
2021-11-07 13:51:45 +01:00
public async Task<Dictionary<T, Route>> GetRoutes<T>(params T[] models) where T : IZeroRouteEntity
2020-11-07 14:32:46 +01:00
{
2021-11-07 13:51:45 +01:00
if (models.Length < 1)
2020-11-07 14:32:46 +01:00
{
return new();
}
2021-07-14 14:34:14 +02:00
T firstExistingModel = models.FirstOrDefault(x => x != null);
if (firstExistingModel == null)
{
return new();
}
2021-11-06 16:27:04 +01:00
if (!TryGetProvider(firstExistingModel, out IRouteProvider routeProvider))
2020-11-07 14:32:46 +01:00
{
return null;
}
2021-11-06 16:27:04 +01:00
RoutingContext context = GetContext();
2021-11-07 13:51:45 +01:00
return (await routeProvider.Find(context, models.Select(x => (IZeroRouteEntity)x).ToArray())).ToDictionary(x => (T)x.Key, x => x.Value);
2021-11-06 16:27:04 +01:00
}
/// <inheritdoc />
public virtual bool TryGetProvider<T>(T model, out IRouteProvider provider) where T : IZeroRouteEntity
{
Type type = model.GetType();
provider = Providers.OrderByDescending(x => x.Priority).FirstOrDefault(x => x.CanHandle(type));
2021-11-06 16:27:04 +01:00
return provider != null;
}
2021-11-07 13:51:45 +01:00
/// <inheritdoc />
public virtual bool TryGetProvider(string alias, out IRouteProvider provider)
{
provider = Providers.OrderByDescending(x => x.Priority).FirstOrDefault(x => x.Alias.Equals(alias, StringComparison.InvariantCultureIgnoreCase));
2021-11-07 13:51:45 +01:00
return provider != null;
}
2021-11-06 16:27:04 +01:00
/// <summary>
/// Map a route to an MVC endpoint
/// </summary>
//public virtual RouteProviderEndpoint MapEndpoint(IResolvedRoute route)
//{
// IEnumerable<Func<IResolvedRoute, RouteProviderEndpoint>> resolvers = Options.Routing.EndpointResolvers.GetAll(route.GetType());
// foreach (Func<IResolvedRoute, RouteProviderEndpoint> resolver in resolvers.Reverse())
// {
// RouteProviderEndpoint endpoint = resolver(route);
// if (endpoint != null)
// {
// return endpoint;
// }
// }
// return Options.Routing.DefaultEndpoint;
//}
/// <summary>
/// Find a persisted route for an entity
/// </summary>
protected virtual async Task<Route> FindRoute(IRouteProvider provider, RoutingContext context, IZeroRouteEntity model)
{
return await provider.Find(context, model);
}
/// <summary>
/// Build a new routing context
/// </summary>
protected virtual RoutingContext GetContext()
{
return new(Store, Context, Store.Session());
2020-10-23 15:50:59 +02:00
}
}
public interface IRoutes
{
/// <summary>
/// Get the URL for an entity
/// </summary>
2021-11-07 13:51:45 +01:00
Task<string> GetUrl<T>(T model) where T : IZeroRouteEntity;
2020-10-23 15:50:59 +02:00
2021-02-10 14:53:56 +01:00
/// <summary>
/// Get the URL for an entity
/// </summary>
2021-11-07 13:51:45 +01:00
Task<string> GetUrl<T>(string id) where T : IZeroRouteEntity;
2021-02-10 14:53:56 +01:00
/// <summary>
/// Get URLs for multiple entities
/// </summary>
2021-11-07 13:51:45 +01:00
Task<Dictionary<T, string>> GetUrls<T>(params T[] models) where T : IZeroRouteEntity;
2020-11-07 14:32:46 +01:00
/// <summary>
2020-10-23 15:50:59 +02:00
/// Get the route object for an entity
/// </summary>
2021-11-07 13:51:45 +01:00
Task<Route> GetRoute<T>(T model) where T : IZeroRouteEntity;
2020-10-23 15:50:59 +02:00
2021-02-10 14:53:56 +01:00
/// <summary>
/// Get the route object for an entity
/// </summary>
2021-11-07 13:51:45 +01:00
Task<Route> GetRoute<T>(string id) where T : IZeroRouteEntity;
2021-02-10 14:53:56 +01:00
2020-11-07 14:32:46 +01:00
/// <summary>
/// Get routes for multiple entities
/// </summary>
2021-11-07 13:51:45 +01:00
Task<Dictionary<T, Route>> GetRoutes<T>(params T[] models) where T : IZeroRouteEntity;
2021-11-06 16:27:04 +01:00
/// <summary>
/// Find a provider for a certain entity
/// </summary>
bool TryGetProvider<T>(T model, out IRouteProvider provider) where T : IZeroRouteEntity;
2021-11-07 13:51:45 +01:00
/// <summary>
/// Find a provider by alias
/// </summary>
bool TryGetProvider(string alias, out IRouteProvider provider);
2020-10-23 15:50:59 +02:00
}
}