/// <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); })); }