问题 - FluentScheduler 在引入 DI 的时候, 引起的 DBContext 在生命周期外的问题
问题描述:
在 ASP.NET Mvc/WebApi 使用 FluentSchedule 的时候,
当执行到定时任务的时候, 会出现 DbContext 已经被 Dispose 的错误
原因:
首先在 Mvc 的 Global 中用 Autofac 注册了所有的 类型为 InstancePerRequest 生命周期,
当注册了任务 Job 的时候, DbContext 存在于生命周期内, 并不会引起什么问题.
在 Job 任务注册结束并且当前请求执行完毕后, 线程会立即退出, 并且 Dispose 掉已经依赖注入过的类
然后当Job任务开始触发的时候, 已经不是由 Mvc 的通道进入了, 所以躲过了 DI 注册的环节
当触发要需要使用 DbContext 的时候, 会发现这个类已经被 Dispose 掉并且没有重新注册过.
解决方案:
所以, 目前比较笨的解决方案就是, 重新在 Job 类中注入一个一次性的类 供这个 Job 使用
(注意, 如果注入的类不是 一次性的(InstancePerDependency), 可能会引发一些错误)
代码如下:
public class PublishSubjectJob : IJob { public int Id; public PublishSubjectJob(int id) { Id = id; } public void Execute() { var builder = new ContainerBuilder(); var baseType = typeof(IDependency); var assemblys = AppDomain.CurrentDomain .GetAssemblies() .Where(d => d.FullName.StartsWith("Sxrong.P2P")) .ToList(); builder.Register(c => new AopInterceptor()).PropertiesAutowired(); builder.RegisterGeneric(typeof(Repository<,>)).As(typeof(IRepository<,>)); builder.RegisterAssemblyTypes(assemblys.ToArray()) .Where(t => baseType.IsAssignableFrom(t) && t != baseType) .AsImplementedInterfaces() .InstancePerDependency() .PropertiesAutowired() .EnableInterfaceInterceptors(); var container = builder.Build(); using (var scope = container.BeginLifetimeScope()) { var service = scope.Resolve<ISubjectAppService>(); service.Publish(Id); } } }


浙公网安备 33010602011771号