有没有人有集成 autofac 和 Quartz.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的所有实现者都不是严格可执行的。
答案 0 :(得分:12)
在不太了解Quartz.Net和IJob
的情况下,我仍会冒险提出建议。
考虑以下作业包装器:
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<SomeJob>
类型。 SomeJob
或InstancePerLifetimeScope
InstancePerDependency
所需的任何依赖关系都将与Owned
实例一起创建和销毁。
答案 1 :(得分:3)