public IInvocationPipelineExecutor CreateExecutor(IInvocationSignature signature) { if (_cache.IsAsync(signature.TargetMethod)) { return(new AsyncInvocationPipelineExecutor(_cacheFactory)); } return(InvocationPipelineExecutor.Instance); }
/// <inheritdoc /> public MethodBoundaryAspect[] CreateBoundaryAspects(IInvocationSignature signature) { if (_aspectDeclarationCollector == null) { _aspectDeclarationCollector = _aspectDeclarationCollectorHolder.Get(); } if (_aspectOrderStrategy == null) { _aspectOrderStrategy = _orderStrategyHolder.Get(); } if (_aspectFinalizer == null) { _aspectFinalizer = _aspectFinalizerHolder.Get(); } if (_dependencySelector == null) { _dependencySelector = _dependencySelectorHolder.Get(); } var methodBoundaryAspects = new List <MethodBoundaryAspect>(); var declarations = _aspectDeclarationCollector.CollectAspectDeclarations <MethodBoundaryAspect>(signature); foreach (var aspect in _aspectOrderStrategy.Order(declarations.Select(d => d.MethodAspect))) { var existingAspect = methodBoundaryAspects.Find(aspect.Equals); // Если у текущего аспекта приоритет выше, чем равного тому, // что уже есть в коллекции, то заменяем его на новый if (existingAspect != null && aspect.Order < existingAspect.Order) { methodBoundaryAspects.Remove(existingAspect); } else if (existingAspect == null) { methodBoundaryAspects.Add(aspect); } } for (var i = 0; i < methodBoundaryAspects.Count; i++) { var currentAspect = methodBoundaryAspects[i]; currentAspect.InternalOrder = currentAspect.Order + i + 1; currentAspect.InternalId = Guid.NewGuid(); currentAspect.HasDependencies = _dependencySelector.HasDependencies(currentAspect.GetType()); currentAspect.IsFinalizable = _aspectFinalizer.IsFinalizable(currentAspect); currentAspect.IsInitializable = ReflectedMethod.IsOverriden( MethodAspect.GetInitializeMethod(currentAspect)); } return(methodBoundaryAspects.ToArray()); }
public IInvocationPipeline CreatePipeline( IInvocationSignature signature, MethodBoundaryAspect[] boundaryAspects, MethodInterceptionAspect interceptionAspect) { if (_cache.IsAsync(signature.TargetMethod)) { return(new AsyncInvocationPipeline(signature, boundaryAspects, interceptionAspect)); } return(new InvocationPipeline(signature, boundaryAspects, interceptionAspect)); }
/// <summary> /// Инициализирует экземпляр <see cref="AsyncInvocationPipeline"/>. /// </summary> public AsyncInvocationPipeline( IInvocationSignature signature, IReadOnlyCollection <MethodBoundaryAspect> boundaryAspects, MethodInterceptionAspect interceptionAspect) : base(signature, boundaryAspects, interceptionAspect) { ReturnTypeInner = signature.InvocationType == InvocationType.AsyncFunction ? signature.Method.ReturnType.GetGenericArguments()[0] : null; CanReturnValue = ReturnTypeInner != null; DefaultReturnValueProvider = new Lazy <object>(() => ReturnTypeInner != null ? ReturnTypeInner.GetDefaultValue() : null); }
private static MethodCall GetAsyncFunctionHandler( IKeyValueCache <Type, MethodCall> cache, IInvocationSignature signature) { var innerType = signature.Method.ReturnType.GetGenericArguments()[0]; return(cache.GetOrAdd(innerType, key => { var method = typeof(AsyncInvocationPipelineExecutor) .GetMethods(BindingFlags.Instance | BindingFlags.NonPublic) .First(m => m.IsGenericMethodDefinition && m.Name == nameof(SignalWhenAwait)) .MakeGenericMethod(innerType); return Expressions.CreateMethodCall(method); })); }
/// <inheritdoc /> public override bool IsWeaveable(IInvocationSignature signature) { if (!signature.DeclaringType.IsInterface) { return(false); } if (IsWeavingSuppressed(signature.Method)) { return(false); } var selector = AspectSelectorHolder.Get(); return(selector.HasAnyAspect(signature.Method) || IsWeaveable(signature.DeclaringType, signature.TargetType)); }
/// <inheritdoc /> public IEnumerable <MethodAspectDeclaration <TAspect> > CollectAspectDeclarations <TAspect>( IInvocationSignature signature) where TAspect : MethodAspect { var selector = _selectorHolder.Get(); var methodAspectDeclarations = selector.SelectAspectDeclarations <TAspect>(signature.TargetMethod); var typeAspectDeclarations = selector.SelectAspectDeclarations <TAspect>(signature.TargetType) .Concat(signature.TargetType.GetInterceptableBaseTypes() .SelectMany(t => selector.SelectAspectDeclarations <TAspect>(t))); var aspectDeclarations = typeAspectDeclarations .Concat(methodAspectDeclarations) .Where(m => m.MethodAspect != null && m.MulticastTarget != MethodAspectMulticastTarget.Undefined); return(aspectDeclarations); }
/// <inheritdoc /> public MethodInterceptionAspect CreateInterceptAspect(IInvocationSignature context) { if (_aspectDeclarationCollector == null) { _aspectDeclarationCollector = _aspectDeclarationCollectorHolder.Get(); } if (_aspectFinalizer == null) { _aspectFinalizer = _aspectFinalizerHolder.Get(); } var aspectDeclarations = _aspectDeclarationCollector .CollectAspectDeclarations <MethodInterceptionAspect>(context) .ToArray(); if (aspectDeclarations.Length > 1) { throw new IvorySharpException( $"Допустимо наличие только одного аспекта типа '{typeof(MethodInterceptionAspect)}'. " + $"На методе '{context.Method.Name}' типа '{context.DeclaringType.FullName}' задано несколько."); } if (aspectDeclarations.Length == 0) { return(BypassMethodAspect.Instance); } if (_dependencySelector == null) { _dependencySelector = _dependencySelectorHolder.Get(); } var declaration = aspectDeclarations.Single(); declaration.MethodAspect.MulticastTarget = declaration.MulticastTarget; declaration.MethodAspect.InternalId = Guid.NewGuid(); declaration.MethodAspect.HasDependencies = _dependencySelector.HasDependencies(declaration.MethodAspect.GetType()); declaration.MethodAspect.IsFinalizable = _aspectFinalizer.IsFinalizable(declaration.MethodAspect); declaration.MethodAspect.IsInitializable = ReflectedMethod.IsOverriden( MethodAspect.GetInitializeMethod(declaration.MethodAspect)); return(declaration.MethodAspect); }
/// <inheritdoc /> public IEnumerable <MethodAspectDeclaration <TAspect> > CollectAspectDeclarations <TAspect>( IInvocationSignature signature) where TAspect : MethodAspect { if (_aspectSelector == null) { _aspectSelector = _aspectSelectorHolder.Get(); } var methodAspectDeclarations = _aspectSelector.SelectAspectDeclarations <TAspect>(signature.Method); var typeAspectDeclarations = _aspectSelector.SelectAspectDeclarations <TAspect>(signature.DeclaringType) .Concat(signature.DeclaringType.GetInterceptableInterfaces() .SelectMany(i => _aspectSelector.SelectAspectDeclarations <TAspect>(i))); var aspectDeclarations = typeAspectDeclarations .Concat(methodAspectDeclarations) .Where(m => m.MethodAspect != null && m.MulticastTarget != MethodAspectMulticastTarget.Undefined); return(aspectDeclarations); }
/// <inheritdoc /> public abstract bool IsWeaveable([NotNull] IInvocationSignature signature);
/// <inheritdoc /> public InvocationWeaveData Get(IInvocationSignature signature) { return(_data.TryGetValue(signature, out var data) ? data : null); }
/// <summary> /// Выполняет перехват вызова исходного метода с применением аспектов. /// </summary> /// <param name="signature">Сигнатура метода.</param> /// <param name="methodCall">Делегат вызова метода.</param> /// <param name="args">Параметры вызова метода.</param> /// <param name="target">Экземпляр сервиса.</param> /// <param name="proxy">Прокси сервиса.</param> /// <returns>Результат вызова метода.</returns> internal object Intercept( IInvocationSignature signature, MethodCall methodCall, object[] args, object target, object proxy) { var invocationData = _weaveDataProvider.Get(signature); if (invocationData == null) { throw new IvorySharpException( $"Не найдена информация о вызываемом методе '{signature.Method.Name}'. " + $"DeclaringType: {signature.DeclaringType.Name} " + $"ImplementationType: {signature.TargetType.Name}"); } if (!invocationData.IsWeaveable) { // Bypass return(methodCall(target, args)); } var invocation = new Invocation(signature, args, proxy, target, methodCall); foreach (var aspect in invocationData.BoundaryAspects) { if (aspect.HasDependencies) { _dependencyInjector.InjectPropertyDependencies(aspect); } if (aspect.IsInitializable) { aspect.Initialize(); } } if (invocationData.InterceptionAspect.HasDependencies) { _dependencyInjector.InjectPropertyDependencies(invocationData.InterceptionAspect); } if (invocationData.InterceptionAspect.IsInitializable) { invocationData.InterceptionAspect.Initialize(); } invocationData.PipelineExecutor.ExecutePipeline(invocationData.Pipeline, invocation); foreach (var aspect in invocationData.BoundaryAspects) { if (aspect.IsFinalizable) { _aspectFinalizer.Finalize(aspect); } } if (invocationData.InterceptionAspect.IsFinalizable) { _aspectFinalizer.Finalize(invocationData.InterceptionAspect); } return(invocation.ReturnValue); }