2021-11-19 12:03:36 +01:00
|
|
|
//using FluentValidation;
|
|
|
|
|
//using Microsoft.Extensions.Logging;
|
|
|
|
|
//using System;
|
|
|
|
|
//using System.Collections.Concurrent;
|
|
|
|
|
//using System.Linq;
|
|
|
|
|
//using System.Linq.Expressions;
|
|
|
|
|
//using System.Threading.Tasks;
|
|
|
|
|
//using zero.Core.Entities;
|
|
|
|
|
//using zero.Core.Options;
|
2020-11-18 15:55:18 +01:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
//namespace zero.Core.Collections
|
|
|
|
|
//{
|
|
|
|
|
// public class CollectionInterceptorHandler : ICollectionInterceptorHandler
|
|
|
|
|
// {
|
|
|
|
|
// protected ConcurrentDictionary<Type, object> Interceptors { get; private set; } = new();
|
2021-08-26 14:05:17 +02:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// protected IZeroOptions Options { get; set; }
|
2021-08-26 14:05:17 +02:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// protected IServiceProvider Services { get; set; }
|
2021-08-26 13:39:30 +02:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// protected ILogger<ICollectionInterceptorHandler> Logger { get; set; }
|
2020-11-18 15:55:18 +01:00
|
|
|
|
|
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// public CollectionInterceptorHandler(IZeroOptions options, IServiceProvider serviceProvider, ILogger<ICollectionInterceptorHandler> logger)
|
|
|
|
|
// {
|
|
|
|
|
// Logger = logger;
|
|
|
|
|
// Options = options;
|
|
|
|
|
// Services = serviceProvider;
|
|
|
|
|
// }
|
2020-11-18 15:55:18 +01:00
|
|
|
|
|
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// /// <inheritdoc />
|
|
|
|
|
// public InterceptorInstruction<T, TParameters> Create<T, TParameters>(string operationName, TParameters parameters)
|
|
|
|
|
// where T : ZeroEntity
|
|
|
|
|
// where TParameters : CollectionInterceptor<T>.Parameters
|
|
|
|
|
// {
|
|
|
|
|
// InterceptorInstruction<T, TParameters> instruction = new(parameters);
|
|
|
|
|
// instruction.Operation = operationName;
|
|
|
|
|
// instruction.BeforeOperationHandler = async expression => await HandleBefore(expression, instruction);
|
|
|
|
|
// instruction.AfterOperationHandler = async expression => await HandleAfter(expression, instruction);
|
2020-11-18 15:55:18 +01:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// return instruction;
|
|
|
|
|
// }
|
2021-08-26 13:39:30 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// /// <summary>
|
|
|
|
|
// /// Calls all matching interceptors with the specified expression
|
|
|
|
|
// /// </summary>
|
|
|
|
|
// internal async Task HandleBefore<T, TParameters>(Expression<Func<ICollectionInterceptor<T>, Task<InterceptorResult<T>>>> expression, InterceptorInstruction<T, TParameters> instruction)
|
|
|
|
|
// where T : ZeroEntity
|
|
|
|
|
// where TParameters : CollectionInterceptor<T>.Parameters
|
|
|
|
|
// {
|
|
|
|
|
// string typeName = (typeof(T)).Name;
|
|
|
|
|
// Func<ICollectionInterceptor<T>, Task<InterceptorResult<T>>> func = default;
|
2021-08-26 13:39:30 +02:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// foreach (InterceptorRegistration registration in ForType(typeof(T)))
|
|
|
|
|
// {
|
|
|
|
|
// if (!TryResolve(registration, out ICollectionInterceptor<T> interceptor))
|
|
|
|
|
// {
|
|
|
|
|
// continue;
|
|
|
|
|
// }
|
2021-08-26 14:05:17 +02:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// if (!interceptor.CanRun(instruction.Parameters))
|
|
|
|
|
// {
|
|
|
|
|
// continue;
|
|
|
|
|
// }
|
2021-11-12 15:16:48 +01:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// if (func == default)
|
|
|
|
|
// {
|
|
|
|
|
// func = expression.Compile();
|
|
|
|
|
// }
|
2020-11-18 15:55:18 +01:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// // we do not log save operations as they are always called for update/create which are already logged beforehand
|
|
|
|
|
// if (instruction.Operation != "save")
|
|
|
|
|
// {
|
|
|
|
|
// Logger.LogDebug("Run interceptor {interceptor} for {type}:{operation}", registration.Name, typeName, instruction.Operation);
|
|
|
|
|
// }
|
2020-11-18 15:55:18 +01:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// InterceptorResult<T> result = await func(interceptor);
|
2021-08-26 13:39:30 +02:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// if (result == default)
|
|
|
|
|
// {
|
|
|
|
|
// result = new();
|
|
|
|
|
// }
|
2021-08-26 13:39:30 +02:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// result.InterceptorHash = registration.Hash;
|
|
|
|
|
// instruction.Results.Add(result);
|
2021-08-26 13:39:30 +02:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// if (result.Result != null)
|
|
|
|
|
// {
|
|
|
|
|
// instruction.EntityResult = result.Result;
|
|
|
|
|
// break;
|
|
|
|
|
// }
|
|
|
|
|
// if (result.Prevent)
|
|
|
|
|
// {
|
|
|
|
|
// break;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
2020-11-18 15:55:18 +01:00
|
|
|
|
|
|
|
|
|
2021-08-26 13:39:30 +02:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// /// <summary>
|
|
|
|
|
// /// Calls all matching interceptors with the specified expression
|
|
|
|
|
// /// </summary>
|
|
|
|
|
// internal async Task HandleAfter<T, TParameters>(Expression<Func<ICollectionInterceptor<T>, Task>> expression, InterceptorInstruction<T, TParameters> instruction)
|
|
|
|
|
// where T : ZeroEntity
|
|
|
|
|
// where TParameters : CollectionInterceptor<T>.Parameters
|
|
|
|
|
// {
|
|
|
|
|
// Func<ICollectionInterceptor<T>, Task> func = default;
|
|
|
|
|
// instruction ??= new();
|
2020-11-18 15:55:18 +01:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// foreach (InterceptorRegistration registration in ForType(typeof(T)))
|
|
|
|
|
// {
|
|
|
|
|
// if (!TryResolve(registration, out ICollectionInterceptor<T> interceptor))
|
|
|
|
|
// {
|
|
|
|
|
// continue;
|
|
|
|
|
// }
|
2021-11-12 15:16:48 +01:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// if (!interceptor.CanRun(instruction.Parameters))
|
|
|
|
|
// {
|
|
|
|
|
// continue;
|
|
|
|
|
// }
|
2021-08-26 14:05:17 +02:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// InterceptorResult<T> beforeResult = instruction?.Results.FirstOrDefault(res => res.InterceptorHash == registration.Hash);
|
2021-08-26 13:39:30 +02:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// if (func == default)
|
|
|
|
|
// {
|
|
|
|
|
// func = expression.Compile();
|
|
|
|
|
// }
|
2020-11-18 15:55:18 +01:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// await func(interceptor);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
2020-11-18 15:55:18 +01:00
|
|
|
|
|
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// /// <summary>
|
|
|
|
|
// /// Get all interceptors for a certain type
|
|
|
|
|
// /// </summary>
|
|
|
|
|
// IOrderedEnumerable<InterceptorRegistration> ForType(Type targetType)
|
|
|
|
|
// {
|
|
|
|
|
// return Options.Interceptors.GetAllItems().Where(x => x.CanHandle(targetType)).OrderByDescending(x => x.Gravity);
|
|
|
|
|
// // return Interceptors.Where(item => item.Types.Count == 0 || item.Types.Any(type => targetType.IsAssignableFrom(type)));
|
|
|
|
|
// }
|
2021-08-26 13:39:30 +02:00
|
|
|
|
|
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// /// <summary>
|
|
|
|
|
// /// Resolves an interceptor from the service provider
|
|
|
|
|
// /// </summary>
|
|
|
|
|
// bool TryResolve<T>(InterceptorRegistration registration, out ICollectionInterceptor<T> interceptor) where T : ZeroEntity
|
|
|
|
|
// {
|
|
|
|
|
// Type type = registration.InterceptorType;
|
2021-08-26 13:39:30 +02:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// if (Interceptors.TryGetValue(type, out object interceptorObj))
|
|
|
|
|
// {
|
|
|
|
|
// interceptor = interceptorObj as ICollectionInterceptor<T>;
|
|
|
|
|
// return interceptor != null;
|
|
|
|
|
// }
|
2021-08-26 13:39:30 +02:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// object service = Services.GetService(type);
|
|
|
|
|
// interceptor = service as ICollectionInterceptor<T>;
|
2021-10-06 11:47:39 +02:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// if (interceptor == null && service != null && service is ICollectionInterceptor)
|
|
|
|
|
// {
|
|
|
|
|
// interceptor = new CollectionInterceptorShim<T>(service as ICollectionInterceptor);
|
|
|
|
|
// }
|
2021-08-26 13:39:30 +02:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// if (interceptor == null)
|
|
|
|
|
// {
|
|
|
|
|
// Logger.LogWarning("Could not resolve interceptor {interceptor}", registration.Name);
|
|
|
|
|
// }
|
2021-08-26 14:05:17 +02:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// Interceptors.TryAdd(type, interceptor);
|
2021-08-26 14:05:17 +02:00
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// return interceptor != null;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
2020-11-18 15:55:18 +01:00
|
|
|
|
|
|
|
|
|
2021-11-19 12:03:36 +01:00
|
|
|
// public interface ICollectionInterceptorHandler
|
|
|
|
|
// {
|
|
|
|
|
// /// <summary>
|
|
|
|
|
// /// Creates a new interceptor instruction
|
|
|
|
|
// /// </summary>
|
|
|
|
|
// InterceptorInstruction<T, TParameters> Create<T, TParameters>(string operationName, TParameters parameters)
|
|
|
|
|
// where T : ZeroEntity
|
|
|
|
|
// where TParameters : CollectionInterceptor<T>.Parameters;
|
|
|
|
|
// }
|
|
|
|
|
//}
|