/// <summary> /// </summary> /// <param name="args"></param> public override void OnInvoke(PostSharp.Aspects.MethodInterceptionArgs args) { string msg = string.Format(Message, args.Arguments); using (new Profiler(msg, _typeName, Level, EnableHirachy)) args.Proceed(); }
/// <summary> /// Cria chave de cache com base nos argumentos do método chamado /// </summary> /// <param name="args">Argumentos do método chamado</param> /// <returns></returns> private string CreateCacheKey(PostSharp.Aspects.MethodInterceptionArgs args) { StringBuilder keyBuilder = new StringBuilder(args.Method.ReflectedType.FullName); keyBuilder.Append("."); keyBuilder.Append(args.Method.Name); keyBuilder.Append("("); var parameters = args.Method.GetParameters(); for (var i = 0; i < parameters.Length; i++) { if (IgnoredParameters != null && IgnoredParameters.Contains(parameters[i].Name)) { continue; } keyBuilder.Append(parameters[i].Name); if (args.Arguments[i] != null) { keyBuilder.Append("{"); keyBuilder.Append(args.Arguments[i]); keyBuilder.Append("}"); } else { keyBuilder.Append("null"); } keyBuilder.Append(";"); } keyBuilder.Append(")"); return(keyBuilder.ToString()); }
/// <summary> /// Intercepta e trata cache em memória /// </summary> /// <param name="args">Argumentos do método chamado</param> public override void OnInvoke(PostSharp.Aspects.MethodInterceptionArgs args) { string cacheKey = CreateCacheKey(args); StaticMemoryCacheItem cache; //Verifica se o cache existe e se o mesmo esta expirado if (!CacheDictionary.TryGetValue(cacheKey, out cache) || (Duration > -1 && (DateTime.UtcNow.Subtract(cache.Date).TotalMilliseconds >= Duration))) { //limpa cache antes da sincronia para buscar o cache atualizado cache = null; if (Synchronize) { //sincroniza chamada lock (Locker) { //somente chama caso o cache seja null (ou seja não tenha sido pre carregado durante o lock) if (cache == null) { cache = CreateCache(args, cacheKey); } } } else { //Executa sem sincronismo de chamada cache = CreateCache(args, cacheKey); } } //Retorna valor args.ReturnValue = cache.Value; }
public override void OnInvoke(PostSharp.Aspects.MethodInterceptionArgs args) { if (IsIgnored) { return; } base.OnInvoke(args); }
/// <summary> /// Executa procedimento padrão e atualiza/salva cache se necessário /// </summary> /// <param name="args">Argumentos do método chamado</param> /// <param name="cacheKey">Chave de cache</param> /// <returns>Retorna item de cache</returns> private StaticMemoryCacheItem CreateCache(PostSharp.Aspects.MethodInterceptionArgs args, string cacheKey) { //executa procedimento padrão args.Proceed(); //salva cache StaticMemoryCacheItem cache = new StaticMemoryCacheItem() { Date = DateTime.UtcNow, Value = args.ReturnValue, Owner = this }; if (!SettedIgnoreValue || args.ReturnValue != ignoreValue) { //armazena/atualiza cache CacheDictionary.AddOrUpdate(cacheKey, cache, (key, oldValue) => cache); } return(cache); }
public void OnException(Exception ex, PostSharp.Aspects.MethodInterceptionAspect sender, PostSharp.Aspects.MethodInterceptionArgs args) { Console.WriteLine("Exception on {0}.{1}:\r\n{2}", args.Method.ReflectedType.FullName, args.Method.Name, ex.Message); }
/// <summary> /// Realiza sobreescrita de chamada no método por chamada de Procedure /// </summary> /// <param name="args">Argumentos da chamada do método</param> public override void OnInvoke(PostSharp.Aspects.MethodInterceptionArgs args) { //caso não seja declarado o ConnectionManager usa o Default var connectionManager = ConnectionManager ?? DefaultManager; //cria ID da chamada var callID = Guid.NewGuid(); try { //caso não seja informado o nome da procedure usa o nome do método como nome da procedure if (ProcedureName == null) { ProcedureName = args.Method.Name; } else { //realiza replace de variaveis no nome da procedure ProcedureName = ProcedureName.Replace("@className", args.Method.ReflectedType.Name); ProcedureName = ProcedureName.Replace("@methodName", args.Method.Name); } //pega conexão com o manager IDbConnection connection = connectionManager.GetOpenedConnection(callID, ConnectionStringName, ConnectionType); //cria comando IDbCommand cmd = connection.CreateCommand(); try { //marca o comando como procedure cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = ProcedureName; var parameters = args.Method.GetParameters(); #region Trata parametros da procedure if (parameters.Length >= 1 && !IsPrimitive(parameters[0].ParameterType)) { //caso tenha mais parametros todos devem ser de saida #region Monta parametros de saida for (var i = 1; i < parameters.Length; i++) { if (!parameters[i].IsOut || !IsPrimitive(parameters[i].ParameterType.GetElementType())) { throw new ArgumentException("If the first parameter is an object other parameters to be output and primitives", parameters[1].Name); } var dbType = DbTypeFromType(parameters[i].ParameterType.GetElementType()); if (dbType == null) { throw new ArgumentException("Invalid Type", parameters[i].Name); } IDbDataParameter parameter = cmd.CreateParameter(); parameter.ParameterName = parameters[i].Name; parameter.DbType = dbType.Value; parameter.Direction = ParameterDirection.Output; cmd.Parameters.Add(parameter); } #endregion //parametro não primitivo não pode ser de saida if (parameters[0].IsOut) { throw new ArgumentException("Objects can not be output parameters", parameters[0].Name); } //o objeto não pode ser nulo var value = args.Arguments[0]; if (value == null) { throw new ArgumentException("Invalid Parameter (Null Value)", parameters[0].Name); } //somente properties publicas var properties = value.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); #region Adiciona propriedades como se fossem parametros de entrada foreach (var property in properties) { var dbType = DbTypeFromType(property.PropertyType); if (dbType == null) { throw new ArgumentException("Invalid Type", property.Name); } IDbDataParameter parameter = cmd.CreateParameter(); parameter.ParameterName = property.Name; parameter.DbType = dbType.Value; parameter.Value = property.GetGetMethod().Invoke(value, null); cmd.Parameters.Add(parameter); } #endregion } else { //adiciona parametros for (int i = 0; i < parameters.Length; i++) { IDbDataParameter parameter = cmd.CreateParameter(); parameter.ParameterName = parameters[i].Name; DbType?dbType; //caso seja de saida não passa valor apenas indica que é de saida if (parameters[i].IsOut) { dbType = DbTypeFromType(parameters[i].ParameterType.GetElementType()); parameter.Direction = ParameterDirection.Output; } else { dbType = DbTypeFromType(parameters[i].ParameterType); parameter.Value = args.Arguments[i]; } if (dbType == null) { throw new ArgumentException("Invalid Type", parameters[i].Name); } parameter.DbType = dbType.Value; cmd.Parameters.Add(parameter); } } #endregion var methodInfo = (args.Method as MethodInfo); //caso não tenmha retorno executa como NonQuery if (methodInfo.ReturnType == typeof(void)) { cmd.ExecuteNonQuery(); } else { #region Realiza tratamentos de retorno //caso tenha retorno executa como reader //verifica se o resultado é uma lista bool isListResult = methodInfo.ReturnType.IsGenericType && (methodInfo.ReturnType.GetGenericTypeDefinition() == typeof(List <>)); //verifica se o resultado é primitivo ou se o item da lista é primitivo bool isPrimitiveResult = isListResult ? IsPrimitive(methodInfo.ReturnType.GetGenericArguments()[0]) : IsPrimitive(methodInfo.ReturnType); using (var reader = cmd.ExecuteReader()) { //instancia objeto de retorno var instance = Activator.CreateInstance(methodInfo.ReturnType); //lê todos os items do reader while (reader.Read()) { int fieldCount = reader.FieldCount; //caso só tenha uma coluna e o item da lista ou resultado for primitivo //lê somente ele if (fieldCount == 1 && isPrimitiveResult) { //caso não seja lista retorna diretamente o primitivo if (!isListResult) { //pega só o primeiro pois não é lista args.ReturnValue = reader.GetValue(0) is DBNull ? null : reader.GetValue(0); break; } else//caso seja lista adiciona na lista { ((IList)instance).Add(reader.GetValue(0) is DBNull ? null : reader.GetValue(0)); } } else { //verifica o tipo do objeto var itemType = isListResult ? methodInfo.ReturnType.GetGenericArguments()[0] : methodInfo.ReturnType; //istancia o objeto var item = Activator.CreateInstance(itemType); //preenche o objeto com as colunas for (int i = 0; i < fieldCount; i++) { try { //caso não tenha uma propriedade com o nome da coluna //ignora o resultado string name = reader.GetName(i); var property = itemType.GetProperty(name, BindingFlags.Public | BindingFlags.Instance); if (property == null) { continue; } //caso achae a propriedade seta o valor property.SetValue(item, reader.GetValue(i) is DBNull ? null : reader.GetValue(i)); } catch (Exception) { } } //caso não seja lista o resultado apenas retorna if (!isListResult) { //pega só o primeiro pois não é lista args.ReturnValue = item; break; } else//caso seja lista adiciona o item na lista { ((IList)instance).Add(item); } } } //caso seja lista retorna o valor if (isListResult) { args.ReturnValue = instance; } } #endregion } //Recupera paametros de saida caso tenha for (int i = 0; i < parameters.Length; i++) { if (parameters[i].IsOut) { //passa argumento validando DBNull para null args.Arguments[i] = (cmd.Parameters[parameters[i].Name] as IDbDataParameter).Value is DBNull ? null : (cmd.Parameters[parameters[i].Name] as IDbDataParameter).Value; } } } finally { //dispensa conexão connectionManager.DispenseConnection(callID, connection); } } catch (Exception ex) { //chama logger para o erro if (Logger != null) { Logger.OnException(ex, this, args); } //marca ultimo erro lastError = ex; //executa o corpo do método args.Proceed(); } }
public override void OnInvoke(PostSharp.Aspects.MethodInterceptionArgs args) { try { System.Net.ServicePointManager.Expect100Continue = Expect100Continue; string url = Uri.ToString(); if (url == null) { url = args.Method.Name; } else { url = url.Replace("@className", args.Method.ReflectedType.Name); url = url.Replace("@methodName", args.Method.Name); } //replace nas tags de app seting while (url.Contains(AppSettingTag)) { var index = url.IndexOf(AppSettingTag); var barra = url.IndexOf('/'); if (barra == -1) { barra = url.IndexOf('\\'); } if (barra == -1) { barra = url.Length; } var appSetting = url.Substring(index, barra); var value = ConfigurationManager.AppSettings[appSetting.Split(':').Last()]; url = url.Replace(appSetting, value ?? string.Empty); } if (MethodNameInUrl) { url += (url.EndsWith("/") || url.EndsWith("\\")) ? args.Method.Name : "/" + args.Method.Name; } var values = new Dictionary <string, object>(); var parameters = args.Method.GetParameters(); //cria parametros na url e valores a serem enviados por get ou post for (var i = 0; i < parameters.Length; i++) { if (url.Contains("{" + parameters[i].Name + "}")) { url = url.Replace("{" + parameters[i].Name + "}", System.Web.HttpUtility.UrlEncode((args.Arguments[i] ?? string.Empty).ToString())); } else if (Header != null && Header.Contains("{" + parameters[i].Name + "}")) { Header = Header.Replace("{" + parameters[i].Name + "}", (args.Arguments[i] ?? string.Empty).ToString()); } else { values.Add(parameters[i].Name, args.Arguments[i]); } } byte[] result; switch (Method) { case HttpRequestMethod.PUT: case HttpRequestMethod.DELETE: case HttpRequestMethod.PATCH: case HttpRequestMethod.POST: result = Post(url, values); break; case HttpRequestMethod.GET: default: result = Get(url, values); break; } if ((args.Method as MethodInfo).ReturnType == typeof(void)) { return; } string text; switch (ResponseType) { case HttpRequestResponseType.JSON: text = Encoding.UTF8.GetString(result); args.ReturnValue = Newtonsoft.Json.JsonConvert.DeserializeObject(text, (args.Method as MethodInfo).ReturnType); break; case HttpRequestResponseType.XML: text = Encoding.UTF8.GetString(result); using (var reader = new StringReader(text)) { XmlSerializer xsResponse = new XmlSerializer((args.Method as MethodInfo).ReturnType); args.ReturnValue = xsResponse.Deserialize(reader); } break; case HttpRequestResponseType.String: args.ReturnValue = Encoding.UTF8.GetString(result); break; case HttpRequestResponseType.Bytes: default: args.ReturnValue = result; break; } } catch (Exception ex) { if (Logger != null) { Logger.OnException(ex, this, args); } lastError = ex; //em caso de resultado inexperado chama metodo para pegar conteudo padrão args.Proceed(); } }