2012-03-07 5 views
5

私はQuartz.Netに基づいてジョブを実行するサービスを実装しようとしています。ジョブはIRepository <>のような依存関係を持つことがあり、リポジトリ実装にはNHibernateのセッションが挿入されます。 (QuartzはWindowsサービスでホストされます)。ジョブは解決するためにNinjectを使用するIJobファクトリの実装(現在はIServiceLocator実装にラップされています)によって解決されます。Quartz.NET、NH ISession&Ninject Scope

仕事スコープ

私はスコープジョブごとにISession複数IRepository <>の中で使用されるジョブごとに作成つのセッションがあるようにNinjectを使用できるようにしたいと思います。

これが可能かどうかわかりませんが、誰かがこれに慣れているのだろうかと疑問に思っていますか?

私は何とかJobコンテキストを使用して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バインディング:

 //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<>)); 

メインの実行:

​​

例仕事:

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 
} 

**リポジトリスニペット:**時間を割いて

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; 
    } 
} 

ありがとう!

更新私はレモの提案を使用して終了 とInCallScope()を使用しています:

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

私は(?正しいかどうか)「初期」からすべてですそれを考えるのが好きな方法を取得します依存関係ツリー全体で同じ項目を再利用し

+1

あなたのソリューションを投稿できますか?私も同じ問題を抱えています。 –

答えて

2
+0

私は現在動作しているように思われるアクティベーションブロックを使用していますが、InCallScope拡張機能に試してみます。ありがとう! –

+0

Remo、アクティベーションブロックを使用してソリューションを投稿できますか? –

+0

@MuriloLima私はこれをアクティベーションブロックを使って解決する方法はありません。私はそれを使用しません。 –