Mik*_*ley 5 nhibernate scope ninject quartz.net
我正在尝试实现一个基于Quartz.Net运行作业的服务.作业可能具有IRepository <>等依赖项,并且存储库实现将注入NHibernate ISession.(Quartz将托管在Windows服务中).通过使用Ninject解析的IJob工厂实现来解析作业(当前包含在IServiceLocator实现中).
工作范围
我希望能够使用Ninject来定位每个作业的ISession,以便每个作业创建一个可以在多个IRepository <>中使用的会话.
不确定这是否可行,但我想知道是否有人有这方面的经验?
我可以以某种方式使用作业上下文来创建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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
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<>));
Run Code Online (Sandbox Code Playgroud)
主要执行:
InitializeIoC();
scheduler = schedulerFactory.GetScheduler();
scheduler.JobFactory = ServiceLocator.Resolve<IJobFactory>();
InitializeJobs();
scheduler.Start();
Run Code Online (Sandbox Code Playgroud)
作业示例:
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
}
Run Code Online (Sandbox Code Playgroud)
**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;
}
}
Run Code Online (Sandbox Code Playgroud)
感谢您抽出宝贵的时间!
更新 我最终使用Remo的建议并使用InCallScope():
Bind<ISession>().ToMethod(ctx => ctx.Kernel.Get<ISessionFactory>().OpenSession()).InCallScope();
Run Code Online (Sandbox Code Playgroud)
我喜欢它的方式(正确与否?)是从"初始"获取的所有内容在整个依赖关系树中重用相同的项目
归档时间: |
|
查看次数: |
1993 次 |
最近记录: |