terça-feira, 27 de dezembro de 2011

Asp.net com EntityFramework: Gerenciando o ciclo de vida do ObjectContext

Olá, pessoal!

Uma dúvida relativamente comum pra quem está começando a usar o Entity Framework em projetos Asp.Net diz respeito ao gerenciamento do ciclo de vida dos objetos ObjectContext.

Qual é a forma correta de gerenciá-los? Em que momento devem ser criados ou destruídos? Por um lado, é muito custoso instanciar um novo contexto toda hora. Você não poderia, por exemplo, criar um a cada método que requeira o uso de um ObjectContext. Por outro, também não podemos simplesmente criar um ObjectContext e deixá-lo viver na memória por toda a sessão de um usuário, ou por todo o ciclo de vida da aplicação.

Uma abordagem amplamente aceita para balancear a quantidade de objetos criados e o tempo de vida de cada um deles é criar um ObjectContext para cada request do Asp.net. Assim, no início de cada request instanciamos um novo ObjectContext, e o destruímos no final da request.

Fazemos isso adicionando um HttpModule ao nosso projeto, e injetando a lógica de criação/destruição dos ObjectContexts nos eventos BeginRequest e EndRequest.

Abaixo, um exemplo dessa implementação. Lembre-se de referenciar o namespace System.Web.

public class ContextManagerModule : IHttpModule
{

    public void Init(HttpApplication application)
    {
        application.BeginRequest += new EventHandler(BeginRequestHandler);
        application.EndRequest += new EventHandler(EndRequestHandler);
    }

    public void BeginRequestHandler(object sender, EventArgs e)
    {
        HttpContext.Current.Items["__DATACONTEXT"] = new EFContext();
    }

    public void EndRequestHandler(object sender, EventArgs e)
    {
        ((EFContext)HttpContext.Current.Items["__DATACONTEXT"]).Dispose();
    }

    public void Dispose() { }
}

Nesse exemplo, EFContext é nossa classe que implementa o ObjectContext do EntityFramework. Substitua pelo nome do ObjectContext do seu projeto.

Agora, sempre que tiver que acessar o ObjectContext, pode fazê-lo assim:

var exemplo = ((EFContext)HttpContext.Current.Items["__DATACONTEXT"]);


Não declare esta variável dentro de um using, pois não queremos que o objeto seja destruído antes do final da request.

O handler que criamos para o evento BeginRequest garante que um ObjectContext ficará disponível para uso ao longo do ciclo de vida de cada nova request.

Já o handler que adicionamos no evento EndRequest da aplicação garantirá que o ObjectContext será destruído logo ao final da request.

Nenhum comentário:

Postar um comentário