据我所知,这在Quartz中是不可能的,我也遇到了同样的问题,我找到的唯一解决方案是使用ServiceLocator并在作业中显式创建作用域。
// Pseudo-Code
public class MyJob : IJob
{
private readonly IServiceLocator _serviceLocator;
public MyJob(IServiceLocator serviceLocator)
{
_serviceLocator = serviceLocator;
}
public async Task Execute(JobExecutionContext context)
{
using(_serviceLocator.BeginScope())
{
var worker = _serviceLocator.GetService<MyWorker>();
await worker.DoWorkAsync();
}
}
}
在本例中,您的工作人员仍处于范围内,但该作业已不再存在。因此,您仍然可以在解决方案的其他地方使用Worker,而且范围仍然有效。
IServiceLocator
也必须由您定义。
在我们的一个项目中,我们使用:
/// <summary>
/// A simple service locator to hide the real IOC Container.
/// Lowers the anti-pattern of service locators a bit.
/// </summary>
public interface IServiceLocator
{
/// <summary>
/// Begins an new async scope.
/// The scope should be disposed explicitly.
/// </summary>
/// <returns></returns>
IDisposable BeginAsyncScope();
/// <summary>
/// Gets an instance of the given <typeparamref name="TService" />.
/// </summary>
/// <typeparam name="TService">Type of the requested service.</typeparam>
/// <returns>The requested service instance.</returns>
TService GetInstance<TService>() where TService : class;
}
/// <summary>
/// SimpleInjector implementation of the service locator.
/// </summary>
public class ServiceLocator : IServiceLocator
{
#region member vars
/// <summary>
/// The SimpleInjector container.
/// </summary>
private readonly Container _container;
#endregion
#region constructors and destructors
public ServiceLocator(Container container)
{
_container = container;
}
#endregion
#region explicit interfaces
/// <inheritdoc />
public IDisposable BeginAsyncScope()
{
return AsyncScopedLifestyle.BeginScope(_container);
}
/// <inheritdoc />
public TService GetInstance<TService>()
where TService : class
{
return _container.GetInstance<TService>();
}
}
如您所见,这只是一个简单的包装器,但有助于向消费者隐藏真正的DI框架。
我希望这有助于理解您需要的实现。