6

我的项目由服务和存储库构成(所有存储库共享数据库上下文)。在我的一个服务层中,我有一个使用存储库写入数据库的异步方法。Web 请求将在此方法开始使用之前完成并处理上下文。我试图理解此答案中所述的NamedScopes。我似乎仍然无法理解如何实现它。我将展示我的项目的结构,并希望有人可以在代码级别帮助我。

绑定

    private static void RegisterServices(IKernel kernel)
    {
        //dbcontext
        kernel.Bind<EntityDatabaseContext>().ToMethod(context => new EntityDatabaseContext()).InRequestScope();

        //unit of work
        kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();

        //repositories
        kernel.Bind<IRepository<Account>>().To<Repository<Account>>().InRequestScope();

        //services
        kernel.Bind<IAuthenticationService>().To<AuthenticationService>().InRequestScope();
    }

AuthenticationService 使用构造函数注入

public AuthenticationService(UnitOfWork unitOfWork, IRepository<Account> accountRepository){}

我的 AuthenticationService 中的一个方法

    //this is a background process
    public Task SomeMethodAsync(string text)
    {
        //spin it off into a new task
        return Task.Factory.StartNew(() => SomeMethod(text));
    }

SomeMethod利用accountRepository. 请告诉我是否需要更多信息。请帮助我解决线程问题,如果 NamedScopes 是解决方案,我该如何实现它?

基本上,正在执行一个后台进程,并且由于请求范围,它正在使用由 ninject 处理的上下文。

4

1 回答 1

6

您应该知道,运行后台线程可能会给您带来很多问题。IIS 可以随时决定回收应用程序池,这将立即终止您的线程(或者在某些情况下根本不执行),从而使您的应用程序处于不一致的状态。

http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx

运行异步操作的最简单和最不容易出错的方法是实现 Windows 服务并将这些异步操作委托给 Windows 服务,例如使用 MSMQ。

如果您仍然想走艰难的路,请阅读HostingEnvironment.RegisterObjectIRegisteredObject防止这些不一致的情况。

Ninject 部分非常简单。只需创建一些作业处理器类,例如MyJobProcessor获取所有必需的依赖项来执行任务。它应该实施INotifyWhenDisposed。最简单的方法是从DisposeNotifyingObject.

public class MyJobProcessor : DisposeNotifyingObject, IRegisteredObject
{
    public void Execute() { ... }
    public void Stop(bool immediate) { ... }
}

将此处理器注入控制器,让任务启动它,并在它完成工作后处理它。

Task.Factory.StartNew(() => 
    { 
        try 
        { 
            processor.Execute(); 
        } 
        finally 
        { 
            processor.Dispose); 
        }
    });

指定它是其依赖项的范围。

Bind<MyJobProcessor>().ToSelf().Named("MyJobProcessor").DefinesNamedScope("MyJobProcessorScope");
Bind<IUnitOfWork>().To<UnitOfWork>().WhenAnyAnchestorNamed("MyJobProcessor").InNamedScope("MyJobProcessorScope");
于 2012-08-02T07:05:22.400 回答