如何在ASP.NET MVC中使用UnitOfWorkPattern和EF Code first实现Quartz.NET工作项

4
我有一个ASP.NET MVC 3.0应用程序,使用EF Code First作为数据层。我实现了一个工作单元模式,将工作单元的上下文绑定到HttpContext.Current.Items [SomeKey]集合中。在控制器的OnActionExecuting / Executed事件中创建和提交工作单元。我使用Windsor Castle实例化存储库。
现在我需要在我的应用程序中定期运行Quartz.net作业,这个作业也需要使用一些存储库。问题是,在SchedulerJob实现中没有可用的HttpContext(确实如此)。在这种情况下,如何从Quartz.net Job实例化一个存储库(它以UnitOfWorkFactory作为构造函数参数)?如何替换缺失的HttpContext?我可能需要实现另一个UnitOfWorkFactory,但我不确定在哪里可以绑定我的上下文以及如何仅为Quartz.net线程注册不同的工厂。您能否给我展示一种方法或模式?谢谢。
2个回答

1
你可能想考虑编写自己的作业工厂并在其中注入存储库。我写了一篇关于如何做到这一点的文章here。Windsor还有一个facitlity,可以直接集成Quartz.net。
最后一条评论......如果您要安排长时间运行的作业或定期运行的作业,则不应将Quartz.Net托管在Web应用程序中。IIS进程回收将无法使调度器正常运行。Windows服务是正确的选择。

谢谢您的回答,我得出结论将删除Quartz作业并实现MSSQL作业的功能,该作业将定期触发。不幸的是,我无法在服务器上安装Windows服务,因为它是商业Web托管服务器,管理员不允许安装任何自定义内容。 - Mikee

0

我同意你的观点,即工作单元不应该依赖于UI层。我读了你的文章,但是我无法从中看出如何将你的方法与存储库模式和DI相结合。我希望通过DI将存储库(或门面)的实例注入到我的控制器中。那么,如何让存储库知道当前的UnitOfWorkScope呢? - Mikee
它的工作方式类似于TransactionScope。只需在存储库中创建一个新的UOW,它将使用由gäller打开的UOW的DbContext。它处理DI,但也提供投票来处理保存(或不保存)。 - Anders Abel
这对于一个存储库似乎是可以的,但如果我需要在更多的存储库上执行复杂操作(对几个不同存储库的几次调用),并且我希望将此复杂操作放在一个范围内,该怎么办?我还注意到,您正在使用私有ThreadStatic变量(scopedDbContext),在ASP MVC中这种方法是否安全?我使用HttpContext.Current.Items集合来存储上下文,因为它是每个HTTP请求的唯一实例。是否保证服务于我的请求的线程不会在UnitOfWorkScope块的中间切换到另一个请求? - Mikee
为了让对多个仓库的调用使用相同的DbContext,这些调用必须被包装在一个UOW中。我通常在我的操作方法中打开一个UOW。只要您不使用线程或异步方法,一切都将在一个线程上运行。但是在同步操作中可能会失败。 - Anders Abel
谢谢您的回答,最终我决定重构我的UOW并实现它,不依赖于HttpContext。我还将删除Quertz.NET作业,并通过MSSQL作业实现其功能。 - Mikee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接