Como configurar o Ninject para criar uma única instância por Controller
Estou tentando usar o Ninject para um aplicativo MVC5 e quero saber se há alguma maneira de configurá-lo para instanciar um único objeto porController
(Não tenho certeza se é o mesmo que por solicitação), use essa instância em qualquerAction
do controlador e uma vez que oAction
terminou liberar todos os recursos que o objeto utilizou.
A classe que eu quero que o Ninject injete em meus controladores implementa a interface IDisposable.
Até agora eu tentei isso:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IUnitOfWork>().To<SqlUnitOfWork>();
}
Mas oDispose
O método nunca é chamado. Eu também tenteiInRequestScope
, mas também não funcionou.
Até agora, a única coisa que realmente funcionou é agrupar a instanciação do objeto que eu preciso em umusing
declaração em CADA ControladorAction
.
Algo assim:
using (var uow = UnitOfWorkFactory.Create())
{
var repos = new UserRepository(uow);
uow.SaveChanges();
}
EDITAR:A classe NinjectWebCommon adicionada pelo pacote Ninject
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
try
{
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
catch
{
kernel.Dispose();
throw;
}
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IUnitOfWork>().To<SqlUnitOfWork>().InRequestScope();
}
}
Como você pode ver no código acima, agora estou usandokernel.Bind<IUnitOfWork>().To<SqlUnitOfWork>().InRequestScope();
, mas oDispose
O método da minha classe ainda nunca é chamado.
Existe realmente alguma maneira de obter com o Ninject o mesmo comportamento que obtemos com umusing
ou seja, quando o objeto criado é usado (a última linha de código no diretórioController
éAction
é processado) oDispose
método desse objeto é chamado?