代码之家  ›  专栏  ›  技术社区  ›  Sachin Chavan bortzmeyer

石英Net和依赖注入或在运行时从外部dll调用作业[重复]

  •  3
  • Sachin Chavan bortzmeyer  · 技术社区  · 15 年前

    目前我正在使用Quartz编写一个服务。NET来计划它的运行。

    我想知道是否有人有过在石英中使用构造函数注入的经验。网络和简单的注射器。

    以下是我希望实现的目标

    public class JobImplementation: IJob
    {
        private readonly IInjectedClass injectedClass;
    
        public JobImplementation(IInjectedClass _injectedClass)
        {
             injectedClass = _injectedClass
        }
    
        public void Execute(IJobExecutionContext _context)
        {
            //Job code
        }
    
    0 回复  |  直到 12 年前
        1
  •  46
  •   Steven    6 年前

    根据 this blog post ,则需要实现一个自定义 IJobFactory ,就像这样:

    public class SimpleInjectorJobFactory : IJobFactory
    {
        private readonly Container container;
        private readonly Dictionary<Type, InstanceProducer> jobProducers;
    
        public SimpleInjectorJobFactory(
            Container container, params Assembly[] assemblies)
        {
            this.container = container;
    
            // By creating producers, jobs can be decorated.
            var transient = Lifestyle.Transient;
            this.jobProducers =
                container.GetTypesToRegister(typeof(IJob), assemblies).ToDictionary(
                    type => type,
                    type => transient.CreateProducer(typeof(IJob), type, container));
        }
    
        public IJob NewJob(TriggerFiredBundle bundle, IScheduler _)
        {
            var jobProducer = this.jobProducers[bundle.JobDetail.JobType];
            return new AsyncScopedJobDecorator(
                this.container, () => (IJob)jobProducer.GetInstance());
        }
    
        public void ReturnJob(IJob job)
        {
            // This will be handled automatically by Simple Injector
        }
    
        private sealed class AsyncScopedJobDecorator : IJob
        {
            private readonly Container container;
            private readonly Func<IJob> decorateeFactory;
    
            public AsyncScopedJobDecorator(
                Container container, Func<IJob> decorateeFactory)
            {
                this.container = container;
                this.decorateeFactory = decorateeFactory;
            }
    
            public async Task Execute(IJobExecutionContext context)
            {
                using (AsyncScopedLifestyle.BeginScope(this.container))
                {
                    var job = this.decorateeFactory();
                    await job.Execute(context);
                }
            }
        }
    }
    

    此外,您还需要以下注册:

    var container = new Container();
    
    container.Options.ScopedLifestyle = new AsyncScopedLifestyle();
    
    var factory = new StdSchedulerFactory();
    
    IScheduler scheduler = await factory.GetScheduler();
    
    scheduler.JobFactory = new SimpleInjectorJobFactory(
        container, 
        Assembly.GetExecutingAssembly()); // assemblies that contain jobs
    
    // Optional: register some decorators
    container.RegisterDecorator(typeof(IJob), typeof(LoggingJobDecorator));
    
    container.Verify();
    
        2
  •  2
  •   holly_cheng    8 年前

    派对迟到了,但是 https://github.com/hbiarge/Quartz.Unity 很适合组合石英。网络与团结。

    IUnityContainer container = new UnityContainer();
    container.AddNewExtension<Quartz.Unity.QuartzUnityExtension>();
    // do your other Unity registrations
    IScheduler scheduler = container.Resolve<IScheduler>();
    
    scheduler.ScheduleJob(
        new JobDetailImpl(myCommandName, typeof(MyCommand)),
        TriggerBuilder.Create()
            .WithCronSchedule(myCronSchedule)
            .StartAt(startTime)
            .Build()
    );
    scheduler.Start();
    
        3
  •  1
  •   BorisSh    4 年前

    使用石英的步骤很少。net的依赖项注入引擎。净核心。

    将nuget软件包添加到项目中:

    Microsoft.Extensions.DependencyInjection
    

    创建自定义JobFactory:

    public class JobFactory : IJobFactory
    {
        protected readonly IServiceProvider _serviceProvider;
    
         public JobFactory(IServiceProvider serviceProvider) 
             => _serviceProvider = serviceProvider;
    
         public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
             => _serviceProvider.GetService(bundle.JobDetail.JobType) as IJob;
    
         public void ReturnJob(IJob job) 
             => (job as IDisposable)?.Dispose();
     }
    

    配置计划程序时指定JobFactory:

     var scheduler = await StdSchedulerFactory.GetDefaultScheduler();
     scheduler.JobFactory = new JobFactory(_serviceProvider);
    

    对于某些人来说,这可能是一个有用的例子,与石英赢得服务。net和DI(来自asp.net核心):

    public class WinService : ServiceBase
    {
        private Scheduler _scheduleManager;
    
        private readonly Startup _startup;
    
        public WinService()
        {
            ServiceName = "SomeWinService";
            _startup = new Startup();
        }
    
        static void Main(string[] args)
        {
            var service = new WinService();
    
            // Working as Windows-service
            if (Console.IsInputRedirected && Console.IsOutputRedirected)
            {
                ServiceBase.Run(service);
            }
            // Working as console app
            else
            {
                service.OnStart(args);
                Console.WriteLine("Press any key to stop...");
                Console.ReadKey();
                service.OnStop();
            }
        }
     
        protected override void OnStart(string[] args)
        {
            _startup.RegisterServices();
            _scheduleManager = new Scheduler(_startup.ServiceProvider);
            _scheduleManager.StartTracking().Wait();
        }
    
        protected override void OnPause()
            => _scheduleManager.PauseTracking().Wait();
    
        protected override void OnContinue()
            => _scheduleManager.ResumeTracking().Wait();
     
        protected override void OnStop()
        {
            _scheduleManager.StopTracking().Wait();
            _startup.DisposeServices();
        }
    }
    
    public class Startup
    {
        private IServiceProvider _serviceProvider;
    
        public IServiceProvider ServiceProvider => _serviceProvider;
    
        public void RegisterServices()
        {        
            _serviceProvider = new ServiceCollection()
                //.AddTransient(...)
                //.AddScoped(...)
                //.AddSingleton(...)
                .BuildServiceProvider();
    
        }
    
        public void DisposeServices()
        {
            if (_serviceProvider == null)
                return;
    
            if (_serviceProvider is IDisposable)
            {
                ((IDisposable)_serviceProvider).Dispose();
            }
        }
    }
    
    public class Scheduler
    {        
        private readonly IServiceProvider _serviceProvider;
       
        private IScheduler _scheduler;
       
        public Scheduler(IServiceProvider serviceProvider) 
            => _serviceProvider = serviceProvider;
       
        public async Task StartTracking()
        {
            _scheduler = await StdSchedulerFactory.GetDefaultScheduler();
            _scheduler.JobFactory = new JobFactory(_serviceProvider);
            await _scheduler.Start();
           
            // Schedule your jobs here
        }
      
        public async Task PauseTracking() => await _scheduler?.PauseAll();
       
        public async Task ResumeTracking() => await _scheduler?.ResumeAll();
      
        public async Task StopTracking() => await _scheduler?.Shutdown();
    }