sábado, 20 de junho de 2009

ASP.NET - Utilizando dependência de cache

Nesse post será tratado a utilização de cache em sites ASP.NET um tema que obrigatoriamente deve ser tratado em sistemas comerciais para garantir um maior desempenho nas operações. Além disso, geralmente a escalabilidade de uma aplicação passa pela correta utilização de cache nas áreas mais utilizadas e que podem utilizar desse mecanismo.

Porém, somente a utilização do cache de dados pode gerar diversos outros problemas como sincronização da atualização dos dados e gestão do consumo de recursos. Para resolvermos alguns desses aspectos estaremos tratando o assunto de dependência de cache que irá auxiliar na gestão das informações facilitando a construção de estruturas mais complexas de relação entre informações.

Para fins de exemplo estaremos tratando os mecanismos de cache de um site de e-commerce, onde podemos ter diversas lojas com diversos setores de informação como promoções, listagem de produtos, preços, etc. No exemplo só estará sendo utilizado o cache de dados para fins de simplificação, mas poderia ser utilizado também OutputCache nesse mecanismo.

Imaginando que queremos armazenar em cache as informações do detalhe de um produto (preços, produtos relacionados, promoções relacionadas e informações técnicas), vitrine de uma categoria de produtos e listagem de produto da categoria.

Todas essas informações podem ser exibidas em momentos diferentes do Site como, por exemplo, promoções de um produto podem ser exibidas no detalhe ou no fechamento da encomenda. Preços são exibidos nas listagens de produtos, fechamento da encomenda e vitrine de categorias.

Sendo assim, queremos desvincular as informações de promoções, preços e informações técnicas, pois cada uma delas possui um tempo diferenciado de atualização para sincronização com o usuário final do Site. Por exemplo, preços geralmente possuem atualização de informação com maior freqüência do que informações técnicas.

Para criar o cache das informações iremos utilizar o componente System.Web.HttpRuntime do ASP.NET que possibilita a utilização do objeto Cache, onde é realizada a gestão de cache da aplicação.

Para inserir um cache utilizaremos o seguinte código:

System.Web.HttpRuntime.Cache.Insert(chaveDoCache, valorDoCache, new System.Web.Caching.CacheDependency(null, new string[] { chaveDoCacheParaDependencia }), DateTime.MaxValue, TimeSpan.Zero);

No exemplo iremos estruturar o cache de maneira que possa ser removido todo o cache da aplicação, somente uma loja, somente um dos sistemas, somente uma área do sistema e um dado específico.

Para isso foram criados métodos de limpeza do cache para cada um dos alvos definidos acima no componente CacheSystem.Helper.

public static void Clear()

public static void Clear(int companyCode)

public static void Clear(int companyCode, string system)

public static void Clear(int companyCode, string system, string subsystem)

public static void Clear(int companyCode, string system, string subsystem, string key)

Toda vez que uma informação é armazenada em cache ela deve passar o valor da chave de sua depenência vinculando assim as operações de atualização entre as duas informações.

Código fonte para download: clique aqui

Detalhes do ambiente de desenvolvimento
  • Linguagem: C#

  • Framework: .NET Framework 3.5 SP 1

  • Ferramenta: Visual Studio 2008 Development Edition

  • Sistema Operacional: Windows XP SP2

domingo, 7 de junho de 2009

ASP.NET - C# - URLs com conteúdo indexável

Nesse post será tratado um tema que cada vez mais encontramos em aplicações Web que é referente a quantidade de informações que podemos disponibilizar nos endereços do Site, ou seja, incluir nas URLs informações relevantes do conteúdo da página ao invés das antigas variáveis com códigos.

Por exemplo ao acessar um produto de um Site geralmente encontrávamos algo como:

http://site.programandosolucoes.com/produto.aspx?codigo=1

Porém com a evolução das tecnologias e principalmente dos motores de pesquisa até mesmo a URL para acesso ao Site deve identificar o seu conteúdo para que sua indexação seja a melhor possível. Sendo assim, passamos a encontrar URLs como a seguinte:

http://site.programandosolucoes.com/produto/Marca-do-produto/nome-do-produto/Visualizar.aspx

Estamos falando em utilizar componentes que auxiliem a tratar URLs com informações e criar assim formas alternativas de acesso do que tínhamos até pouco tempo atrás. Isso é utilizado principalmente em blogs, sites de notícias e sites de vendas, por exemplo.

Para isso temos nas novas versões do ASP.NET a funcionalidade RewritePath do componente HttpContext que possibilita tratar a troca do endereço novo (com informações) para o antigo (com passagem de parâmetros) sem que o usuário final perceba isso. Sendo assim, visualmente a URL com informações do conteúdo sempre leva para a mesma página antiga (funcionam os 2 mecanismos).

Para o exemplo estaremos utilizando um Site de vendas de produtos que aceitará o nome do produto no endereço.

Uma das soluções é construirmos um novo módulo (realizando a interface IHttpModule) que irá receber a URL com as informações e irá traduzir para o formato que o sistema espera. Partindo sempre do pressuposto que as regras são definidas sobre valores únicos (descrições na URL são únicas) e apontam sempre para um mesmo conteúdo. Exemplo do código fonte utilizado:


   1:      public class UrlRewrite : IHttpModule

   2:      {

   3:          #region IHttpModule Members

   4:   

   5:          public void Dispose()

   6:          {

   7:              //

   8:          }

   9:   

  10:          public void Init(HttpApplication context)

  11:          {

  12:              context.BeginRequest += new EventHandler(context_BeginRequest);

  13:          }

  14:   

  15:          void context_BeginRequest(object sender, EventArgs e)

  16:          {

  17:              HttpContext context = ((HttpApplication)sender).Context;

  18:              string path = context.Request.Path.ToUpperInvariant();

  19:              string url = context.Request.RawUrl.ToUpperInvariant();

  20:   

  21:              if (url.Contains("/PRODUTO/"))

  22:              {

  23:                  string[] parameters = url.Substring(url.IndexOf("/PRODUTO/")+1).Split('/');

  24:                  string type = parameters[0];

  25:                  string product = parameters[1];

  26:                  string operation = parameters[2];

  27:   

  28:                  if (type.Equals("PRODUTO") && operation.Contains("VISUALIZAR"))

  29:                  {

  30:                      context.RewritePath("~/Produto.aspx?id=" + Data.Product.GetProductByDescription(product).Id);

  31:                  }

  32:              }

  33:          }

  34:   

  35:          #endregion

  36:      }


* Nesse exemplo está sendo utilizada somente a extensão ".aspx" por ser mais simples de exemplificar. Para tratar URLs com outras extensões é necessário configurar o IIS para tratar a extensão escolhida utilizando o componente do ASP.NET "c:\windows\...\aspnet_isapi.dll".

Segue abaixo vídeo que exibe passo-a-passo a solução:


Código fonte para download: clique aqui

Detalhes do ambiente de desenvolvimento
  • Linguagem: C#

  • Framework: .NET Framework 3.5 SP 1

  • Ferramenta: Visual Studio 2008 Development Edition

  • Sistema Operacional: Windows XP SP2