Castle.ActiveRecord e SessionScope – resolvendo problemas de sessão

Há algum tempo eu vinha tendo um problema com a utilização de coleções Lazy Load nas propriedades de algumas classes, através do meu framework.

É bom que se fale logo no início que esse framework (no seu módulo de persistência) é baseado no padrão Repository, utilizando, entre outros métodos, o ActiveRecord, do Castle Project, para modelar as classes e acessar o banco (rodando Linq nas consultas).

Pois bem, dado isto, um problema que encontrei diversas vezes foi na hora de chamar uma propriedade que é uma coleção e estava setado como Lazy=true no atributo “HasMany”.

Ocorria o seguinte erro:

Initializing[ClasseModelada#1]-failed to lazily initialize a collection of role: PropriedadeDeLista, no session or session was closed

Ou seja, o servidor indicava que não conseguia acessar os dados da coleção lazy por falta de uma sessão do ActiveRecord com o banco.

Durante muito tempo eu usei uma solução bem simples, de apenas 1 linha de código, e que funciona perfeitamente, mas que era chata, pois quando a esquecia, lá vinha o erro novamente:

using(new SessionScope())
{
... // código que acessa a propriedade Lazy
}

Para resolver esse “pequeno” problema, temos duas soluções possíveis:

A primeira, mais complicada, é inserindo no arquivo Global.asax.cs o seguinte código:

protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Items.Add("ar.sessionscope", new Castle.ActiveRecord.SessionScope());
}

protected void Application_EndRequest(object sender, EventArgs e)
{
try
{
Castle.ActiveRecord.SessionScope scope = HttpContext.Current.Items["ar.sessionscope"] as Castle.ActiveRecord.SessionScope;
if (scope != null)
scope.Dispose();
}
catch (Exception ex)
{
HttpContext.Current.Trace.Warn("Error", "EndRequest: " + ex.Message, ex);
}
}

Ou seja, a cada requisição da aplicação, é adicionado no contexto atual um SessionScope novo. Ao final da requisição, esse SessionScope é destruído.

Uma alternativa (melhor, na minha opinião) é a 2ª abordagem:

Apague todo o código acima e, no arquivo Web.config, insira o seguinte código:

<system.web>
<httpModules>
<add name="ar.sessionscope" type="Castle.ActiveRecord.Framework.SessionScopeWebModule, Castle.ActiveRecord"/>
</httpModules>
</system.web>

Pronto! O gerenciador dos módulos Http fará a manipulação do SessionScope automaticamente para a aplicação.

Todas as opções são eficientes, porém a 1ª abordagem perde um pouco em desempenho, pois, provavelmente, você não acessa o banco em 100% das requisições da sua aplicação. É necessário verificar se o mesmo ocorre com a 2ª opção. Mas esta análise de desempenho eu deixo pra você colocar nos comentários.

Até a próxima!

Ofertas Relacionadas
Sony Ericsson Xperia Mini Pro Sk17 3g Wi Fi Android Hd Gps
Sony Ericsson Xperia Mini Pro Sk17 3g Wi Fi Android Hd Gps
Mais info»
R$ 535.00
até 18x de 40.13
Celular Hiphone 4 Mp30 2 Chips Wi Fi Tv Fm Java Msn Touch 4g
Celular Hiphone 4 Mp30 2 Chips Wi Fi Tv Fm Java Msn Touch 4g
Mais info»
R$ 119.00
até 18x de 8.93
Smartphone Samsung Galaxy Ace S5830 800mhz 3g Wi Fi Gps
Smartphone Samsung Galaxy Ace S5830 800mhz 3g Wi Fi Gps
Mais info»
R$ 610.00
até 18x de 45.75

Tags: , ,

Postar um comentário ou Deixe um Trackback
seperator

Postar um comentário

Seu email nunca será publicado ou compartilhado. Campos obrigatórios estão marcados com *

*
*
*