Olá, Eduardo!
Você pegou a ideia certa de como funciona sim. Antes, nós tínhamos que criar a instância em todo método de acesso ao banco de dados no DAO.
A classe TransactionFilter herda de ActionFilterAttribute. Veja o nome... ActionFilterAttribute. Ou seja, um filtro vinculado às actions realizadas no sistema.
Nela, tem o construtor:
public TransactionFilter(ISession session)
{
this.session = session;
}
Só que, quem cria esse filtro é o servidor, quando executamos a aplicação. Então, se isso é feito em tempo de execução, quem cria a sessão? Tem que ser o servidor também!!!
Para isso, usamos o Ninject. Isso foi feito com o código abaixo:
private static void RegisterServices(IKernel kernel)
{
// registro dos outros componentes
int ordemExecucao = 1;
kernel.BindFilter<TransactionFilter>(FilterScope.Global, ordemExecucao);
}
Nesse código, nós registramos o filtro no Ninject. Isso significa dizer que, tudo que o filtro precisar, o Ninject irá criar uma instância e passar, como o ISession do construtor!!!
Com a ISession agora sendo recebida pelo construtor, tem os outros dois métodos do filtro:
public override void OnActionExecuting(ActionExecutingContext contexto)
{
session.BeginTransaction();
}
public override void OnActionExecuted(ActionExecutedContext contexto)
{
session.Transaction.Commit();
session.Close();
}
O primeiro método é executado quando a action é executada. Ou seja, no início da action, abrimos uma transação. Depois disso, o código do controller e do DAO são executados.
No final de tudo, quando a controller fizer o response para o cliente, no final, significa que a action terminou de ser executada, aí ele automaticamente faz o commit da transação e fecha a sessão para não ficar um recurso pesado obsoleto sem ser usado.
Ficou mais claro assim?