Ninject Scope and System.Threading.Timer

2019-07-30 15:17发布

问题:

How to invoke a new Ninject context on a Timer task? Having a hard time configuring ninject scope to unitofwork. If I set as InRequestScope() it doesn't work on non request tasks. So I set up like below so that I can get InThreadScope for tasks:

kernel.Bind<IUnitOfWork>().To<myEntities>().InScope(ctx => HttpContext.Current ?? StandardScopeCallbacks.Thread(ctx));

But that way, when I set up a timer

Timer timer = new Timer(_ => DelayedDisconnect(chatUser.User.AuthorizationId), null, TimeSpan.FromSeconds(10), TimeSpan.FromMilliseconds(-1));

the dbContext doesn't refresh with the new database values.

public void DelayedDisconnect(string authorizationId)
    {
        var myChatUser = GetChatUserByClaimedIdentifier(authorizationId);

        if (!myChatUser.ChatClients.Any()) // old state (doesn't reflect database changes from 10 seconds ago).

So...How to invoke a new Ninject "context" to reflect current state / db values?

回答1:

You really shouldn't run background tasks in an ASP.NET application. Write a service to do this. http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx

By using a windows service it gets really easy. Setup a timer that requests a SomeProcessor that does all the work from the kernel. Now you can use the NamedScope extension and define that the processor is the scope for some objects like the UoW

kernel.Bind<SomeProcessor>().ToSelf().DefinesNamedScope("Processor");
kernel.Bind<IUoW>().To<UoW>().InNamedScope("Processor");