/// <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()); }
/// <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); }
private void Initialize(SerializedProperty property) { if (!m_Initialized) { m_Initialized = true; m_SubObjects = property.FindPropertyRelative("m_SubObjects"); m_AddItemMethod = property.FindMethodRelative("Add", typeof(Type)); m_RemoveItemMethod = property.FindMethodRelative("Remove", typeof(int)); m_HasInstanceOfTypeMethod = property.FindMethodRelative("HasInstanceOfType", typeof(Type)); m_ReoderableList = new ReorderableList(m_SubObjects.serializedObject, m_SubObjects) { draggable = true }; m_ReoderableList.onAddCallback += OnComponentAdded; m_ReoderableList.onRemoveCallback += OnComponentRemoved; m_ReoderableList.drawHeaderCallback += OnDrawHeader; m_ReoderableList.drawElementCallback += OnDrawElement; } }
/// <inheritdoc /> public MethodInfo GetMethodMap(Type targetType, MethodInfo interfaceMethod) { Debug.Assert(targetType != null, "targetType != null"); Debug.Assert(interfaceMethod != null, "interfaceMethod != null"); var key = new MethodMapCacheKey(targetType, interfaceMethod); if (_methodMapCacheKey.TryGetValue(key, out var map)) { return(map); } map = ReflectedMethod.GetMethodMap(targetType, interfaceMethod); if (_methodMapCacheKey.TryAdd(key, map)) { return(map); } return(_methodMapCacheKey.TryGetValue(key, out var cmap) ? cmap : map); }
/// <inheritdoc /> public IInvocationWeaveDataProvider Create(Type declaredType, Type targetType) { var key = new TypePair(declaredType, targetType); return(_providerCache.GetOrAdd(key, typeKey => { var invocationsData = new ConcurrentDictionary <IInvocationSignature, InvocationWeaveData>( InvocationSignature.InvocationSignatureMethodEqualityComparer.Instance); var declaredMethods = typeKey.DeclaringType.GetMethods() .Union(typeKey.DeclaringType.GetInterfaces() .SelectMany(i => i.GetMethods())); foreach (var declaredMethod in declaredMethods) { var targetMethod = ReflectedMethod.GetMethodMap(typeKey.ImplementationType, declaredMethod); if (targetMethod == null) { throw new IvorySharpException( $"Не удалось найти метод '{declaredMethod.Name}' в типе '{typeKey.ImplementationType.Name}'"); } var signature = new InvocationSignature( declaredMethod, targetMethod, typeKey.DeclaringType, typeKey.ImplementationType, declaredMethod.GetInvocationType()); if (_weavePredicate == null) { _weavePredicate = _weavePredicateHolder.Get(); } var isWeaveable = _weavePredicate.IsWeaveable(signature); if (!isWeaveable) { invocationsData.TryAdd(signature, InvocationWeaveData.Unweavable()); continue; } if (_factory == null) { _factory = _preInitializerHolder.Get(); } var boundaryAspects = _factory.CreateBoundaryAspects(signature); var interceptAspect = _factory.CreateInterceptAspect(signature); if (_pipelineFactory == null) { _pipelineFactory = _pipelineFactoryHolder.Get(); } var pipeline = _pipelineFactory.CreatePipeline(signature, boundaryAspects, interceptAspect); var executor = _pipelineFactory.CreateExecutor(signature); invocationsData.TryAdd(signature, InvocationWeaveData.Weavable(pipeline, executor, boundaryAspects, interceptAspect)); } return new InvocationWeaveDataProvider(invocationsData); })); }