问题 - 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);
            }
        }
    }

 

posted @ 2018-05-18 10:11  `Laimic  阅读(510)  评论(0)    收藏  举报