【问题标题】:Autofac and Quartz.Net IntegrationAutofac 和 Quartz.Net 集成
【发布时间】:2011-02-05 22:33:09
【问题描述】:

有人有集成autofacQuartz.Net的经验吗?如果是这样,最好在哪里控制生命周期管理 - IJobFactory,在 IJob 的执行中,还是通过事件侦听器?


现在,我正在使用自定义 autofac IJobFactory 来创建 IJob 实例,但我没有简单的方法来插入 IJobFactory 中的 ILifetimeScope 以确保任何昂贵的资源在 IJob 中注入的被清理。作业工厂只是创建一个作业实例并返回它。这是我目前的想法(希望有更好的想法......)

  • 看起来大多数 AutoFac 集成以某种方式将ILifetimeScope 包裹在他们创建的工作单元周围。显而易见的蛮力方法似乎是将ILifetimeScope 传递给IJob 并让Execute 方法创建一个子ILifetimeScope 并在那里实例化任何依赖项。这似乎有点过于接近服务定位器模式,反过来又似乎违背了 autofac 的精神,但它可能是确保正确处理范围的最明显方式。

  • 我可以插入一些 Quartz 事件来处理 Job 执行堆栈的不同阶段,并在那里处理生命周期管理。这可能需要做更多的工作,但如果能够更清晰地分离关注点,这可能是值得的。

  • 确保 IJob 是 IServiceComponent 类型的简单包装器,它将完成所有工作,并将其请求为 Owned<T>Func<Owned<T>>。我喜欢 autofac 的这种感觉,但我不喜欢它对 IJob 的所有实现者都不是严格执行的。

【问题讨论】:

    标签: autofac quartz.net


    【解决方案1】:

    在不太了解 Quartz.Net 和 IJobs 的情况下,我仍然会冒险提出建议。

    考虑以下作业包装器:

    public class JobWrapper<T>: IJob where T:IJob
    {
        private Func<Owned<T>> _jobFactory;
    
        public JobWrapper(Func<Owned<T>> jobFactory)
        {
            _jobFactory = jobFactory;
        }
    
    
        void IJob.Execute()
        {
            using (var ownedJob = _jobFactory())
            {
                var theJob = ownedJob.Value;
                theJob.Execute();
            }
        }
    }
    

    鉴于以下注册:

    builder.RegisterGeneric(typeof(JobWrapper<>));
    builder.RegisterType<SomeJob>();
    

    作业工厂现在可以解析此包装器:

    var job = _container.Resolve<JobWrapper<SomeJob>>();
    

    注意:lifetime scope 将作为ownedJob 实例的一部分创建,在本例中为Owned&lt;SomeJob&gt; 类型。 SomeJob 所需的任何依赖项,即 InstancePerLifetimeScopeInstancePerDependency 都将与 Owned 实例一起创建和销毁。

    【讨论】:

    • 感谢您抽出宝贵时间回复。我喜欢这个想法,因为它是我在原始问题中的第三次头脑风暴的更明确的版本。仍然困扰我的是我无法控制生命周期范围。基本上,我想在自己的LifetimeScope 中运行每个IJob,几乎相当于WCF 服务调用。不幸的是,Quartz IJobFactory 很火而且忘记了我所知道的,所以如果我真的想要明确的范围边界,我可能不得不深入研究 Quartz 侦听器系统。
    • @dfaivre - 我已经纠正了我的代码中的一个错误,我忘记了ownedJob.Value 部分。也许我的意图现在更清楚了。
    • 我不知道 Owned 创建了一个范围;很有用。我认为这可能是最直接的方法,而不是深入研究 Quartz 堆栈。如果工作不是JobWrapper&lt;&gt; 类型的,我可能会增加我的IJobFactory 来抛出(只是这样我晚上睡得更好......)。再次感谢您的深刻见解。
    • @dfaivre - 太好了,很高兴为您提供帮助 :)
    • 所以,几年后,我意识到我误解了这个答案,但这是一个比我第一次更好的答案。我明确地将我的工作创建为JobWrapper&lt;&gt; 的子类,它仍然将我与 Autofac 紧密耦合,实际上,我应该让AutofacJobFactory 为我动态创建包装器,允许底层 IJob 只声明它的依赖关系。有些日子...
    【解决方案2】:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-15
      • 2017-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多