Как создать привязку синглтона с истекающим сроком действия? - PullRequest
5 голосов
/ 04 мая 2011

Как создать привязку для одноэлементного объекта глобальной области действия, срок действия экземпляра которого истекает через некоторое время? После истечения срока действия объекта я бы хотел, чтобы Ninject обслуживал новый экземпляр, пока не истечет срок действия этого экземпляра и т. Д ...

Псевдо-связывание, чтобы донести идею:

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

Я не ищу этот точный синтаксис, а скорее способ получить желаемый результат. По сути это было бы похоже на использование Ninject в качестве кеша скользящего приложения.

Обновление Методология, предложенная Яном, была правильной. Мне просто пришлось немного его подправить, потому что использование DateTime в качестве контекстного ключа по какой-то причине не сработало. Вот что я закончил:

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);   

Ответы [ 2 ]

2 голосов
/ 04 мая 2011

Вы можете использовать InScope (Func scope). Как указано в документации:

Указывает, что экземпляры, активированные через привязку, должны использоваться повторно до тех пор, пока объект возвращенный предоставленным обратным вызовом остается живым (то есть не был собран сборщиком мусора).

Вам потребуется реализовать собственную настраиваемую область, которая обрабатывает ваш сценарий. Хорошим примером того, как реализовать собственную область видимости, является именованное расширение области действия

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

2 голосов
/ 04 мая 2011

Вы по сути определяете временную область. Вы можете выполнить привязку с помощью пользовательской функции области действия и через некоторое время вернуть значение null.

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

Я не могу проверить это сейчас, но это может сработать.

...