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

186 lines
4.9 KiB
C#
Raw Normal View History

2021-11-19 16:11:12 +01:00
using Microsoft.Extensions.Logging;
using Raven.Client.Documents.Linq;
namespace zero.Routing;
public class Routes : IRoutes
{
public const char PATH_SEPERATOR = '/';
protected IZeroContext Context { get; set; }
protected IZeroStore Store { get; set; }
protected ILogger<Routes> Logger { get; set; }
protected IEnumerable<IRouteProvider> Providers { get; set; }
public Routes(IZeroContext context, IZeroStore store, ILogger<Routes> logger, IEnumerable<IRouteProvider> providers)
{
Context = context;
Store = store;
Logger = logger;
Providers = providers;
}
/// <inheritdoc />
2021-12-01 15:54:11 +01:00
public async Task<string> GetUrl<T>(T model) where T : ISupportsRouting => (await GetRoute(model))?.Url;
2021-11-19 16:11:12 +01:00
/// <inheritdoc />
2021-12-01 15:54:11 +01:00
public async Task<string> GetUrl<T>(string id) where T : ISupportsRouting => (await GetRoute<T>(id))?.Url;
2021-11-19 16:11:12 +01:00
/// <inheritdoc />
2021-12-01 15:54:11 +01:00
public async Task<Dictionary<T, string>> GetUrls<T>(params T[] models) where T : ISupportsRouting => (await GetRoutes(models)).ToDictionary(x => x.Key, x => x.Value?.Url);
2021-11-19 16:11:12 +01:00
/// <inheritdoc />
2021-12-01 15:54:11 +01:00
public async Task<Route> GetRoute<T>(string id) where T : ISupportsRouting
2021-11-19 16:11:12 +01:00
{
T model = await GetContext().Session.LoadAsync<T>(id);
return await GetRoute(model);
}
/// <inheritdoc />
2021-12-01 15:54:11 +01:00
public async Task<Route> GetRoute<T>(T model) where T : ISupportsRouting
2021-11-19 16:11:12 +01:00
{
if (model == null)
{
return null;
}
if (!TryGetProvider(model, out IRouteProvider routeProvider))
{
return null;
}
RoutingContext context = GetContext();
return await FindRoute(routeProvider, context, model);
}
/// <inheritdoc />
2021-12-01 15:54:11 +01:00
public async Task<Dictionary<T, Route>> GetRoutes<T>(params T[] models) where T : ISupportsRouting
2021-11-19 16:11:12 +01:00
{
if (models.Length < 1)
{
return new();
}
T firstExistingModel = models.FirstOrDefault(x => x != null);
if (firstExistingModel == null)
{
return new();
}
if (!TryGetProvider(firstExistingModel, out IRouteProvider routeProvider))
{
return null;
}
RoutingContext context = GetContext();
2021-12-01 15:54:11 +01:00
return (await routeProvider.Find(context, models.Select(x => (ISupportsRouting)x).ToArray())).ToDictionary(x => (T)x.Key, x => x.Value);
2021-11-19 16:11:12 +01:00
}
/// <inheritdoc />
2021-12-01 15:54:11 +01:00
public virtual bool TryGetProvider<T>(T model, out IRouteProvider provider) where T : ISupportsRouting
2021-11-19 16:11:12 +01:00
{
Type type = model.GetType();
provider = Providers.OrderByDescending(x => x.Priority).FirstOrDefault(x => x.CanHandle(type));
return provider != null;
}
/// <inheritdoc />
public virtual bool TryGetProvider(string alias, out IRouteProvider provider)
{
provider = Providers.OrderByDescending(x => x.Priority).FirstOrDefault(x => x.Alias.Equals(alias, StringComparison.InvariantCultureIgnoreCase));
return provider != null;
}
/// <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>
2021-12-01 15:54:11 +01:00
protected virtual async Task<Route> FindRoute(IRouteProvider provider, RoutingContext context, ISupportsRouting model)
2021-11-19 16:11:12 +01:00
{
return await provider.Find(context, model);
}
/// <summary>
/// Build a new routing context
/// </summary>
protected virtual RoutingContext GetContext()
{
return new(Store, Context, Store.Session());
}
}
public interface IRoutes
{
/// <summary>
/// Get the URL for an entity
/// </summary>
2021-12-01 15:54:11 +01:00
Task<string> GetUrl<T>(T model) where T : ISupportsRouting;
2021-11-19 16:11:12 +01:00
/// <summary>
/// Get the URL for an entity
/// </summary>
2021-12-01 15:54:11 +01:00
Task<string> GetUrl<T>(string id) where T : ISupportsRouting;
2021-11-19 16:11:12 +01:00
/// <summary>
/// Get URLs for multiple entities
/// </summary>
2021-12-01 15:54:11 +01:00
Task<Dictionary<T, string>> GetUrls<T>(params T[] models) where T : ISupportsRouting;
2021-11-19 16:11:12 +01:00
/// <summary>
/// Get the route object for an entity
/// </summary>
2021-12-01 15:54:11 +01:00
Task<Route> GetRoute<T>(T model) where T : ISupportsRouting;
2021-11-19 16:11:12 +01:00
/// <summary>
/// Get the route object for an entity
/// </summary>
2021-12-01 15:54:11 +01:00
Task<Route> GetRoute<T>(string id) where T : ISupportsRouting;
2021-11-19 16:11:12 +01:00
/// <summary>
/// Get routes for multiple entities
/// </summary>
2021-12-01 15:54:11 +01:00
Task<Dictionary<T, Route>> GetRoutes<T>(params T[] models) where T : ISupportsRouting;
2021-11-19 16:11:12 +01:00
/// <summary>
/// Find a provider for a certain entity
/// </summary>
2021-12-01 15:54:11 +01:00
bool TryGetProvider<T>(T model, out IRouteProvider provider) where T : ISupportsRouting;
2021-11-19 16:11:12 +01:00
/// <summary>
/// Find a provider by alias
/// </summary>
bool TryGetProvider(string alias, out IRouteProvider provider);
}