/// <summary> /// Creates and caches a new, closed/invokable continue-with method out of ContinueWith<T> for each method called on the target. /// </summary> /// <param name="input">The input.</param> /// <returns>MethodInfo.</returns> MethodInfo GetContinueWith( IMethodInvocation input) { if (input == null) { throw new ArgumentNullException(nameof(input)); } if (!input.IsAsyncCall()) { return(null); } var returnType = ((MethodInfo)input.MethodBase).ReturnType; var handlerTypeReturnType = new HandlerTypeReturnType(GetType(), returnType); MethodInfo continueWith; // if we have it cached already - return it using (SyncMethodToContinueWith.ReaderLock()) if (HandlerTypeReturnTypeToContinueWith.TryGetValue(handlerTypeReturnType, out continueWith)) { return(continueWith); } // get the continueWith MethodInfo MethodInfo genericContinueWith; using (SyncHandlerToGenericContinueWith.ReaderLock()) genericContinueWith = HandlerToGenericContinueWith[GetType()]; // if it is not overridden, it will be null! continueWith = genericContinueWith?.MakeGenericMethod(returnType); using (SyncMethodToContinueWith.WriterLock()) return(HandlerTypeReturnTypeToContinueWith[handlerTypeReturnType] = continueWith); }
/// <summary> /// Initializes a new instance of the <see cref="BaseCallHandler{T}"/> class. /// </summary> protected BaseCallHandler() { // Get the method info for an overridden ContinueWith<TResult>, if exists in the inheriting call handler: using (SyncHandlerToGenericContinueWith.UpgradableReaderLock()) if (!HandlerToGenericContinueWith.TryGetValue(GetType(), out MethodInfo continueWithGeneric)) { continueWithGeneric = GetType().GetMethod( nameof(ContinueWith), BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(IMethodInvocation), typeof(IMethodReturn), typeof(T) }, null); var isOverridden = continueWithGeneric.IsOverridden() || GetType().GetMethods().Any(mi => mi.Name == nameof(DoContinueWith) && mi.IsOverridden()); using (SyncHandlerToGenericContinueWith.WriterLock()) HandlerToGenericContinueWith[GetType()] = isOverridden ? continueWithGeneric : null; } }