protected override object Invoke(MethodInfo targetMethod, object[] args) { object result = null; var sourceTargetMethod = GetSourceTargetMethod(targetMethod); try { if (targetMethod == null || sourceTargetMethod == null) { throw new ArgumentException($"Middleware Framework could not get {nameof(targetMethod)}"); } var cacheKey = string.Empty; var isGetFromCache = false; var cachingProfile = sourceTargetMethod.GetCustomAttribute <CachingAttribute>(); var isCaching = sourceTargetMethod.IsCaching(); if (isCaching) { cacheKey = sourceTargetMethod.GenerateCacheKey(args, Client.GetCachePrefix(ServiceVersion)); var cachedData = CacheManager.Get(cacheKey); if (cachedData != null) { isGetFromCache = true; if (!sourceTargetMethod.HasServiceResponse()) { result = cachedData; } else { result = Activator.CreateInstance(sourceTargetMethod.ReturnType); var propertyInfo = sourceTargetMethod.ReturnType.GetProperty("Data"); propertyInfo?.SetValue(result, cachedData); } } } ServiceLogManager <TClient, TUser> .OnBeforeMethodCall(Client, User, sourceTargetMethod, args, isGetFromCache); if (!isGetFromCache) { try { result = sourceTargetMethod.Invoke(_decorated, args); } catch (Exception ex) { ServiceLogManager <TClient, TUser> .OnException(Client, User, ex, sourceTargetMethod); if (sourceTargetMethod.HasServiceResponse()) { result = ex.ToMessageResponse(sourceTargetMethod); } else { throw; } } sourceTargetMethod.CheckDropCache(); if (isCaching && result != null) { var cacheData = result; if (sourceTargetMethod.HasGenericServiceResponse()) { var propertyInfo = sourceTargetMethod.ReturnType.GetProperty("Data"); cacheData = propertyInfo?.GetValue(result); } CacheManager.Set(cacheKey, cacheData, cachingProfile.CacheDuration); } } if (sourceTargetMethod.HasGenericServiceResponse()) { var propertyInfo = sourceTargetMethod.ReturnType.GetProperty(nameof(ServiceResponse.HasAuth)); var hasAuth = (bool)(propertyInfo?.GetValue(result) ?? false); if (!hasAuth) { propertyInfo?.SetValue(result, User != null); } } ServiceLogManager <TClient, TUser> .OnAfterMethodCall(Client, User, sourceTargetMethod, args, result, isGetFromCache); return(result); } catch (Exception ex) { var targetException = ex.InnerException ?? ex; ServiceLogManager <TClient, TUser> .OnException(Client, User, targetException, sourceTargetMethod); throw targetException; } }