public void execute_found_job()
        {
            var sl = Substitute.For<IContainer>();
            var scope = Substitute.For<IContainerScope>();
            var job = Substitute.For<IBackgroundJob>();
            sl.CreateScope().Returns(scope);
            scope.Resolve(job.GetType()).Returns(job);
            scope.ResolveAll<IBackgroundJob>().Returns(new[] {job});

            var sut = new BackgroundJobManager(sl);
            sut.StartInterval = TimeSpan.FromSeconds(0);
            sut.Start();
            Thread.Sleep(100);

            job.Received().Execute();
        }
        public void trigger_ScopeClosed_before_closing_it_after_job_Execution()
        {
            var sl = Substitute.For<IContainer>();
            var job = Substitute.For<IBackgroundJob>();
            var scope = Substitute.For<IContainerScope>();
            sl.CreateScope().Returns(scope);
            scope.Resolve(job.GetType()).Returns(job);
            scope.ResolveAll<IBackgroundJob>().Returns(new[] { job });
            ScopeClosingEventArgs actual = null;

            var sut = new BackgroundJobManager(sl);
            sut.StartInterval = TimeSpan.FromSeconds(0);
            sut.ScopeClosing += (o, e) => actual = e;
            sut.Start();
            Thread.Sleep(100);

            actual.Should().NotBeNull();
        }
        private void RunDemo()
        {
            
            var adapter = CreateContainer();
            _serviceManager = new ApplicationServiceManager(adapter);
            _serviceManager.ServiceFailed += OnApplicationFailure;
            _serviceManager.Start();

            _jobManager = new BackgroundJobManager(adapter);
            _jobManager.JobFailed += OnJobFailed;
            _jobManager.Start();


            //Press enter to shut down
            Console.ReadLine();

            _jobManager.Stop();
            _serviceManager.Stop();

            Console.WriteLine("Done, press enter to exit");
            Console.ReadLine();
        }
        public void trigger_ScopeClosed_before_closing_it_even_if_job_execution_fails()
        {
            var sl = Substitute.For<IContainer>();
            var scope = Substitute.For<IContainerScope>();
            var job = Substitute.For<IBackgroundJob>();
            sl.CreateScope().Returns(scope);
            scope.Resolve(job.GetType()).Returns(job);
            scope.ResolveAll<IBackgroundJob>().Returns(new[] { job });

            var sut = new BackgroundJobManager(sl);
            sut.StartInterval = TimeSpan.FromSeconds(0);
            sut.Start();
            Thread.Sleep(100);

            job.Received().Execute();
        }
        public void consume_exceptions_thrown_by_event_subscribers()
        {
            var sl = Substitute.For<IContainer>();
            var scope = Substitute.For<IContainerScope>();
            var job = Substitute.For<IBackgroundJob>();
            var job2 = Substitute.For<IBackgroundJob>();
            job.When(x => x.Execute()).Do(x => { throw new SqlNullValueException(); });
            sl.CreateScope().Returns(scope);
            scope.ResolveAll<IBackgroundJob>().Returns(new[] { job, job2 });
            scope.Resolve(job.GetType()).Returns(job);
            scope.Resolve(job2.GetType()).Returns(job2);

            var sut = new BackgroundJobManager(sl);
            sut.StartInterval = TimeSpan.FromSeconds(0);
            sut.JobFailed += (o, e) => { throw new Exception(); };
            sut.Start();
            Thread.Sleep(100);

            job2.Received().Execute();
        }
        public void run_next_async_job_even_if_first_fails()
        {
            var sl = Substitute.For<IContainer>();
            var scope = Substitute.For<IContainerScope>();
            var job = Substitute.For<IBackgroundJobAsync>();
            var job2 = Substitute.For<IBackgroundJobAsync>();
            job.When(x => x.ExecuteAsync()).Do(x => { throw new SqlNullValueException(); });
            sl.CreateScope().Returns(scope);
            scope.Resolve(job.GetType()).Returns(job);
            scope.Resolve(job2.GetType()).Returns(job2);
            scope.ResolveAll<IBackgroundJobAsync>().Returns(new[] { job, job2 });

            var sut = new BackgroundJobManager(sl);
            sut.StartInterval = TimeSpan.FromSeconds(0);
            sut.Start();
            Thread.Sleep(100);

            job2.Received().ExecuteAsync();
        }
        public void report_job_failure_using_the_event_and_include_NoJob_if_type_cant_be_resolved()
        {
            var sl = Substitute.For<IContainer>();
            var scope = Substitute.For<IContainerScope>();
            var job = Substitute.For<IBackgroundJob>();
            BackgroundJobFailedEventArgs actual = null;
            job.When(x => x.Execute()).Do(x => { throw new InvalidDataException(); });
            sl.CreateScope().Returns(scope);
            scope.ResolveAll<IBackgroundJob>().Returns(new[] { job });

            var sut = new BackgroundJobManager(sl);
            sut.StartInterval = TimeSpan.FromSeconds(0);
            sut.Start();
            sut.JobFailed += (sender, args) => actual = args;
            Thread.Sleep(100);

            actual.Exception.Should().BeOfType<InvalidOperationException>();
            actual.Job.Should().BeOfType<BackgroundJobManager.NoJob>();
        }