2013-06-04 24 views
15

Tôi đang cố gắng để có được Quartz.net (2.1.2) để làm việc với một container IoC (autofac), như tôi có dịch vụ tôi cần phải sử dụng trong lịch trình công việc. Tôi đã tìm thấy các bài viết tương tự về chủ đề này, nhưng tôi dường như không thể tìm thấy một bài đăng với một ví dụ đăng ký cụ thể cho autofac.Làm thế nào để tạo một công việc của Quartz.NET yêu cầu tiêm với autofac

Các bài giao dịch sau với cùng một vấn đề tôi đang gặp khó:

How to schedule task using Quartz.net 2.0?

Tuy nhiên, phần Tôi tin rằng tôi đang thiếu là khi câu trả lời nói "Và đừng quên đăng ký công việc trong container IoC ". Tôi không chắc chắn làm thế nào để làm điều này chính xác, như tất cả mọi thứ tôi đã cố gắng cho đến nay đã không làm việc.

Trong ví dụ sau, "HelloJob" sẽ chạy, nhưng bất cứ khi nào tôi cố gắng tiêm releaseService vào "ReleaseJob" nó từ chối chạy.

Cập nhật: Tôi đã đánh dấu mã trong phần DependencyRegistration.cs nơi tôi tin rằng vấn đề là.

Cập nhật 2: Một số liên kết có liên quan có liên quan đến những gì tôi cần phải làm gì và có thể giúp đỡ (Tôi đã trải qua tất cả nhưng vẫn không thể tìm ra cách để có được điều này làm việc với autofac):

CÁCH SỬ DỤNG Quartz.NET theo cách PRO? - http://blog.goyello.com/2009/09/21/how-to-use-quartz-net-in-pro-way/

Autofac và Quartz.NET - http://blog.humann.info/post/2013/01/30/Autofac-and-QuartzNET.aspx

Constructor tiêm với Quartz.NET và Injector Simple - Constructor injection with Quartz.NET and Simple Injector

ASP.Net MVC 3, Ninject và thạch anh .Net - Làm thế nào để? - ASP.Net MVC 3, Ninject and Quartz.Net - How to?

Đây là mã có liên quan:

Global.asax

protected void Application_Start() 
    { 
     AreaRegistration.RegisterAllAreas(); 

     RegisterGlobalFilters(GlobalFilters.Filters); 
     RegisterRoutes(RouteTable.Routes); 

     var dependencyRegistration = new DependencyRegistration(); 
     dependencyRegistration.Register(); 

     ModelValidatorProviders.Providers.Clear(); 
     ModelValidatorProviders.Providers.Add(new FluentValidationModelValidatorProvider(new ValidatorFactory())); 

     DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false; 
    } 

DependencyRegistration.cs

public class DependencyRegistration 
{ 
    public void Register() 
    { 
     var builder = new ContainerBuilder(); 

     builder.RegisterControllers(Assembly.GetExecutingAssembly()); 
     builder.RegisterAssemblyModules(Assembly.GetExecutingAssembly()); 

     // Validation 
     builder.RegisterType<ValidatorFactory>() 
      .As<IValidatorFactory>() 
      .InstancePerHttpRequest(); 

     AssemblyScanner findValidatorsInAssembly = AssemblyScanner.FindValidatorsInAssembly(Assembly.GetExecutingAssembly()); 
     foreach (AssemblyScanner.AssemblyScanResult item in findValidatorsInAssembly) 
     { 
      builder.RegisterType(item.ValidatorType) 
       .As(item.InterfaceType) 
       .InstancePerHttpRequest(); 
     } 

     // Schedule 
     builder.Register(x => new StdSchedulerFactory().GetScheduler()).As<IScheduler>(); 

     // Schedule jobs 
     builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).Where(x => typeof(IJob).IsAssignableFrom(x)); 

     var container = builder.Build(); 
     DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 

     //Schedule 
     IScheduler sched = container.Resolve<IScheduler>(); 
     sched.JobFactory = new AutofacJobFactory(container); 
     sched.Start(); 

     IJobDetail job = JobBuilder.Create<ReleaseJob>() 
       .WithIdentity("1Job") 
       .Build(); 

     ITrigger trigger = TriggerBuilder.Create() 
      .WithIdentity("1JobTrigger") 
      .WithSimpleSchedule(x => x 
       .RepeatForever() 
       .WithIntervalInSeconds(5) 
      ) 
      .StartNow() 
      .Build(); 

     sched.ScheduleJob(job, trigger); 

     job = JobBuilder.Create<HelloJob>() 
       .WithIdentity("2Job") 
       .Build(); 

     trigger = TriggerBuilder.Create() 
      .WithIdentity("2JobTrigger") 
      .WithSimpleSchedule(x => x 
       .RepeatForever() 
       .WithIntervalInSeconds(5) 
      ) 
      .StartNow() 
      .Build(); 

     sched.ScheduleJob(job, trigger); 
    } 
} 

JobFactory.cs

public class AutofacJobFactory : IJobFactory 
{ 
    private readonly IContainer _container; 

    public AutofacJobFactory(IContainer container) 
    { 
     _container = container; 
    } 

    public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) 
    { 
     return (IJob)_container.Resolve(bundle.JobDetail.JobType); 
    } 

    public void ReturnJob(IJob job) 
    { 
    } 
} 

ReleaseJob.cs

public class ReleaseJob : IJob 
{ 
    private readonly IReleaseService _releaseService; 

    public ReleaseJob(IReleaseService releaseService) 
    { 
     this._releaseService = releaseService; 
    } 

    public void Execute(IJobExecutionContext context) 
    { 
     Debug.WriteLine("Release running at " + DateTime.Now.ToString()); 
    } 
} 

public class HelloJob : IJob 
{ 
    public void Execute(IJobExecutionContext context) 
    { 
     Debug.WriteLine("Hello job at " + DateTime.Now.ToString()); 
    } 
} 

ReleaseServiceModel.cs

public class ReleaseServiceModule : Module 
{ 
    protected override void Load(ContainerBuilder builder) 
    { 
     builder.RegisterType<ReleaseService>() 
      .As<IReleaseService>() 
      .InstancePerLifetimeScope(); 
    } 
} 
+0

Bạn đã tiết kiệm cho tôi thời gian tìm hiểu điều này. Cảm ơn rất nhiều Tomas. – slashp

Trả lời

5

Cuối cùng tôi đã tìm ra vấn đề là gì.

Dịch vụ phát hành của tôi đang sử dụng kho lưu trữ dữ liệu được tạo với phạm vi khác.

Tôi đã phát hiện ra điều này bằng cách tạo một dịch vụ thử nghiệm mới không làm gì ngoài trả về một chuỗi và thao tác đó được đưa vào công việc thạch anh.

Khi phát hiện ra điều này, tôi đã thay đổi phạm vi của kho lưu trữ được gọi bởi dịch vụ phát hành và sau đó dịch vụ phát hành bắt đầu hoạt động bên trong công việc thạch anh.

Lời xin lỗi của tôi đối với bất kỳ ai đã xem câu hỏi này để thử và giúp tôi. Bởi vì mã của dịch vụ phát hành không được liệt kê, sẽ rất khó để tìm ra những gì đã sai.

Tôi đã cập nhật mã bằng các ràng buộc làm việc cuối cùng mà tôi đã sử dụng cho thạch anh với autofac.

+0

Xin chào Thomas - Xin lỗi vì đã sao lưu một bài đăng cũ, nhưng bạn đã có ví dụ về cách bạn thay đổi phạm vi dịch vụ của mình để tính đến điều này. Tôi rơi vào cùng một cái bẫy mà im không quá kinh nghiệm trong tiêm phụ thuộc và không thể làm điều này để làm việc:/ – SM3RKY

+0

Tôi tin rằng nó đã thay đổi phạm vi từ "InstancePerHttpRequest" mà không làm việc, để "InstancePerLifetimeScope" mà đã làm việc, trong kho lưu trữ và mô-đun dịch vụ phát hành. – Tomas

0

Vấn đề là AutofacJobFactory của bạn không tạo ra ReleaseJob (bạn đang làm điều này với JobBuilder.Create<ReleaseJob>() thay), vì vậy các container IoC là không nhận thức được nó instantiation nghĩa dependency injection không thể xảy ra.

Các mã sau đây nên làm việc:

sched = schedFact.GetScheduler(); 
sched.JobFactory = new AutofacJobFactory(container); 
sched.Start(); 

// construct job info 
JobDetailImpl jobDetail = new JobDetailImpl("1Job", null, typeof(ReleaseJob)); 

ITrigger trigger = TriggerBuilder.Create() 
    .WithIdentity("1JobTrigger") 
    .WithSimpleSchedule(x => x 
     .RepeatForever() 
     .WithIntervalInSeconds(5) 
    ) 
    .StartNow() 
    .Build(); 

sched.ScheduleJob(jobDetail, trigger); 

Lưu ý rằng trong ví dụ này, chúng ta không sử dụng JobBuilder.Create<ReleaseJob>() nữa, thay vào đó chúng tôi vượt qua các chi tiết của công việc được tạo ra thông qua các đối tượng JobDetailImpl và bằng cách làm này scheduler của jobfactory (các AutofacJobFactory) có trách nhiệm instantiating công việc và Dependency tiêm có thể xảy ra.

+0

Tôi đã thực hiện thay đổi bạn đã đề xuất. Tôi đã xóa JobBuilder.Create <> và thay thế nó bằng ví dụ của bạn. Tuy nhiên, hành vi vẫn như cũ. HelloJob chạy nhưng ReleaseJob thì không. – Tomas

+0

Tôi giả định rằng phương thức AutofacJobFactory.NewJob() hiện đang được gọi? Nếu vậy, đó là một vấn đề với ràng buộc của bạn. Khi thử nghiệm, bạn có thể thay đổi các dòng vấn đề được đánh dấu có liên quan thành 'builder.RegisterType .As ();' và cũng thay đổi dòng tiếp theo thành 'JobDetailImpl jobDetail = new JobDetailImpl (" 1Job ", null, typeof (IJob)); 'Lưu ý rằng điều này sẽ kiểm tra xem các ràng buộc có đang được giải quyết hay không, nhưng bạn sẽ cần một nhà máy trừu tượng nếu bạn muốn khởi tạo nhiều kiểu' IJob' – dcarson

+0

Tôi đặt một điểm ngắt trên AutofacJobFactory.NewJob(). Nó được gọi cho HelloJob, nhưng không bao giờ có vẻ kích hoạt từ ReleaseJob. Tôi cũng đã thay đổi kiểu builder và job như đã chú ý tới IJob và chỉ chạy chúng mỗi lần một. HelloJob đã hoạt động trở lại, ReleaseJob thì không. Cám ơn tất cả sự giúp đỡ từ trước tới nay - Tôi không có kinh nghiệm với những ràng buộc và nghi ngờ rằng họ là vấn đề ở đây, tôi không chắc phải cố gắng làm gì tiếp theo để họ làm việc. – Tomas