2012-03-07 11 views
5

Próbuję zaimplementować usługę, która będzie wykonywać zadania w oparciu o Quartz.Net. Zadania mogą mieć zależności takie jak IRepository <>, a implementacja repozytorium będzie zawierała iniekcję NHibernate. (Kwarc będzie hostowany w usłudze Windows). Zadania są rozwiązywane poprzez implementację fabryki IJob, która używa rozwiązania Ninject do rozstrzygnięcia (obecnie jest zawarty w implementacji IServiceLocator).Quartz.NET, NH ISession & Ninject Scope

Zakres pracy

chciałbym móc używać Ninject do ZAKRES ISession na zadanie tak, że istnieje jedna sesja stworzona za zadania, które mogą być używane w wielu IRepository <> 's.

Nie jestem pewien, czy to możliwe, ale zastanawiam się, czy ktoś ma z tym doświadczenie?

Czy mogę w jakiś sposób użyć kontekstu zadania do utworzenia zakresu używanego przez Kernel.InScope (???).

Quartz.Net IJobFactory:

public class JobFactory : IJobFactory 
{ 
    readonly IServiceLocator locator; 

    public JobFactory(IServiceLocator locator) 
    { 
     this.locator = locator; 
    } 

    public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) 
    { 
     try 
     {    
      var jobDetail = bundle.JobDetail; 
      var jobType = jobDetail.JobType; 

      return (IJob)locator.Resolve(jobType); 
     } 
     catch (Exception e) 
     { 
      var se = new SchedulerException("Problem instantiating class", e); 
      throw se; 
     } 
    } 
} 

Ninject Wiązania:

 //Service Locator 
     Bind<IServiceLocator>().To<NinjectAdapter>(); 

     //Quartz Bindings 
     Bind<IJobFactory>().To<JobFactory>(); 

     //NHibernate Bindings 
     Bind<ISessionFactory>().ToMethod(ctx => ctx.Kernel.Get<NHibernateConfiguration>().BuildSessionFactory()).InSingletonScope(); 
     Bind<ISession>().ToMethod(ctx => ctx.Kernel.Get<ISessionFactory>().OpenSession());// ToDo: Figure out how to scope session 

     //Repository Bindings 
     Bind(typeof (IRepository<>)).To(typeof (ReadWriteRepository<>)); 

główna Wykonanie:

 InitializeIoC(); 
     scheduler = schedulerFactory.GetScheduler(); 
     scheduler.JobFactory = ServiceLocator.Resolve<IJobFactory>(); 
     InitializeJobs(); 
     scheduler.Start(); 

Przykład pracy:

public class TestJob3 : IJob 
{ 
    private readonly IRepository<Customer> repo; 
    private readonly IRepository<Order> orderRepo; 

    public TestJob3(IRepository<Customer> repo, IRepository<Order> orderRepo) 
    { 
     //orderRepo and repo should have the same ISession 

     this.repo = repo; 
     this.oderRepo = orderRepo; 
     System.Diagnostics.Debug.WriteLine("Job 3 Created"); 
    } 

    #region Implementation of IJob 

    public void Execute(IJobExecutionContext context) 
    { 
     System.Diagnostics.Debug.WriteLine("Job 3 Executing"); 
     using (var scope = new TransactionScope()) 
     { 
      var customer = repo.GetById(1); 
      customer.Name = "Blue Goats"; 
      repo.Save(customer); 
      scope.Complete(); 
     } 
    } 

    #endregion 
} 

** Repository Snippet: **

public class ReadWriteRepository<TEntity> : IRepository<TEntity> where TEntity : class, IRootEntity 
{ 
    private readonly ISession session; 

    public ReadWriteRepository(ISession session) 
    { 
     this.session = session; 
    } 

    public virtual TEntity GetById(int id) 
    { 
     var entity = session.Get<TEntity>(id); 
     return entity; 
    } 

    public virtual TEntity Save(TEntity entity) 
    { 
     session.SaveOrUpdate(entity); 
     return entity; 
    } 
} 

Dzięki za poświęcenie czasu!

Aktualizacja skończyło się stosując sugestię Remo i używam InCallScope():

Bind<ISession>().ToMethod(ctx => ctx.Kernel.Get<ISessionFactory>().OpenSession()).InCallScope(); 

tak jak lubię myśleć o tym (? Poprawne, czy nie) to wszystko z "początkowy" get ponowne wykorzystanie tych samych elementów w całym drzewie zależności

+1

Czy możesz zamieścić swoje rozwiązanie? Mam ten sam problem. –

Odpowiedz

2
+0

Obecnie używam bloku aktywacyjnego, który wydaje się działać, ale spróbuję wypróbować rozszerzenie InCallScope. Dzięki! –

+0

Remo, czy możesz zamieścić swoje rozwiązanie za pomocą bloku aktywacyjnego? –

+0

@MuriloLima Nie mam do tego rozwiązania przy użyciu bloku aktywacyjnego. Nie użyłbym tego. –