2011-05-04 12 views
5

¿Cómo puedo crear un enlace para un objeto singleton con ámbito global cuya instancia caduque después de un cierto período de tiempo? Una vez que el objeto ha expirado me gustaría Ninject para servir a una nueva instancia hasta que expire instancia, etc ...¿Cómo creo un enlace singleton que caduque?

Pseudo unión a transmitir la idea de:

Bind<Foo>().ToSelf() 
    .InSingletonScope() 
    .WithExpiration(someTimeSpan); 

No estoy buscando esa sintaxis exacta, sino más bien una forma de terminar con el resultado deseado. En esencia, sería como usar Ninject como un caché de aplicaciones deslizante.

Actualización La metodología que Ian sugirió era correcta. Solo tuve que ajustarlo un poco porque usar un DateTime como la clave de contexto no funcionó por alguna razón. Esto es lo que terminé con:

var someTimeInFuture = DateTime.Now.AddSeconds(10); 
var fooScopeObject = new object(); 

Func<IContext, object> scopeCall = ctx => 
{ 
    if (someTimeInFuture < DateTime.Now) 
    { 
     someTimeInFuture = DateTime.Now.AddSeconds(10); 
     fooScopeObject = new object(); 
    } 

    return fooScopeObject; 
}; 


Kernel.Bind<Foo>() 
    .ToSelf() 
    .InScope(scopeCall); 
+0

Que normalmente no desea almacenar en caché los servicios, pero los datos de los servicios de gestión. Entonces, ¿por qué realmente quieres hacer esto? – Steven

+1

Entiendo completamente lo que dices. Esto se usó para conseguir un almacenamiento en caché barato en una aplicación brownfield sin hacer ningún cambio arquitectónico importante ... lo que significa que fuimos con un antipatrón a propósito para buscar algún rendimiento en un par de lugares problemáticos sin cambiar la arquitectura. –

+0

Gracias por aclarar. Eso suena como una razón válida. Al final, la ingeniería (software) se trata de intercambios. – Steven

Respuesta

2

Está definiendo esencialmente un alcance temporizado. Puede vincular utilizando una función de ámbito personalizado y devolver nulo después de un período de tiempo.

var someTimeInFuture = DateTime.Now.AddMinutes(5); 
Func<IContext,object> scopeCall = ctx => DateTime.Now > someTimeInFuture ? null : someTimeInFuture; 
Kernel.Bind<Foo>().ToSelf().InScope(scopeCall); 

No puedo probar esto ahora, pero eso puede funcionar.

+0

Creo que necesitaría Func scopeCall = ctx => DateTime.Now> someTimeInFuture? null: someTimeInFuture; –

+0

Gracias Daniel. Fijo. –

+0

¡Muchas gracias! Esto fue más o menos correcto, salvo que la llamada al alcance no funcionó correctamente al devolver un DateTime. Las estructuras no deben funcionar para determinar el alcance (mi mejor estimación). –

2

Puede usar InScope (ámbito de Func). A medida que la documentación indica:

Indica que los casos activan a través de la unión debe ser re-utilizado, siempre y cuando el objeto devuelto por la devolución de llamada proporcionado permanece vivo (es decir, no ha sido basura recogida).

Debería implementar su propio ámbito personalizado que maneje su escenario. Un buen ejemplo de cómo implementar su propio alcance es la extensión del ámbito con nombre

https://github.com/ninject/ninject.extensions.namedscope

Cuestiones relacionadas