//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; //namespace zero.Core.Collections //{ // public class CollectionInterceptorHandler : ICollectionInterceptorHandler // { // protected ConcurrentDictionary Interceptors { get; private set; } = new(); // protected IZeroOptions Options { get; set; } // protected IServiceProvider Services { get; set; } // protected ILogger Logger { get; set; } // public CollectionInterceptorHandler(IZeroOptions options, IServiceProvider serviceProvider, ILogger logger) // { // Logger = logger; // Options = options; // Services = serviceProvider; // } // /// // public InterceptorInstruction Create(string operationName, TParameters parameters) // where T : ZeroEntity // where TParameters : CollectionInterceptor.Parameters // { // InterceptorInstruction instruction = new(parameters); // instruction.Operation = operationName; // instruction.BeforeOperationHandler = async expression => await HandleBefore(expression, instruction); // instruction.AfterOperationHandler = async expression => await HandleAfter(expression, instruction); // return instruction; // } // /// // /// Calls all matching interceptors with the specified expression // /// // internal async Task HandleBefore(Expression, Task>>> expression, InterceptorInstruction instruction) // where T : ZeroEntity // where TParameters : CollectionInterceptor.Parameters // { // string typeName = (typeof(T)).Name; // Func, Task>> func = default; // foreach (InterceptorRegistration registration in ForType(typeof(T))) // { // if (!TryResolve(registration, out ICollectionInterceptor interceptor)) // { // continue; // } // if (!interceptor.CanRun(instruction.Parameters)) // { // continue; // } // if (func == default) // { // func = expression.Compile(); // } // // 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); // } // InterceptorResult result = await func(interceptor); // if (result == default) // { // result = new(); // } // result.InterceptorHash = registration.Hash; // instruction.Results.Add(result); // if (result.Result != null) // { // instruction.EntityResult = result.Result; // break; // } // if (result.Prevent) // { // break; // } // } // } // /// // /// Calls all matching interceptors with the specified expression // /// // internal async Task HandleAfter(Expression, Task>> expression, InterceptorInstruction instruction) // where T : ZeroEntity // where TParameters : CollectionInterceptor.Parameters // { // Func, Task> func = default; // instruction ??= new(); // foreach (InterceptorRegistration registration in ForType(typeof(T))) // { // if (!TryResolve(registration, out ICollectionInterceptor interceptor)) // { // continue; // } // if (!interceptor.CanRun(instruction.Parameters)) // { // continue; // } // InterceptorResult beforeResult = instruction?.Results.FirstOrDefault(res => res.InterceptorHash == registration.Hash); // if (func == default) // { // func = expression.Compile(); // } // await func(interceptor); // } // } // /// // /// Get all interceptors for a certain type // /// // IOrderedEnumerable 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))); // } // /// // /// Resolves an interceptor from the service provider // /// // bool TryResolve(InterceptorRegistration registration, out ICollectionInterceptor interceptor) where T : ZeroEntity // { // Type type = registration.InterceptorType; // if (Interceptors.TryGetValue(type, out object interceptorObj)) // { // interceptor = interceptorObj as ICollectionInterceptor; // return interceptor != null; // } // object service = Services.GetService(type); // interceptor = service as ICollectionInterceptor; // if (interceptor == null && service != null && service is ICollectionInterceptor) // { // interceptor = new CollectionInterceptorShim(service as ICollectionInterceptor); // } // if (interceptor == null) // { // Logger.LogWarning("Could not resolve interceptor {interceptor}", registration.Name); // } // Interceptors.TryAdd(type, interceptor); // return interceptor != null; // } // } // public interface ICollectionInterceptorHandler // { // /// // /// Creates a new interceptor instruction // /// // InterceptorInstruction Create(string operationName, TParameters parameters) // where T : ZeroEntity // where TParameters : CollectionInterceptor.Parameters; // } //}