背景

       最近在做一个需要,就是在Job中捕获异样,而后通过邮件或者音讯的形式推送给指定人员,在需要实现的过程中遇到的一个注入问题,觉得很有意思,特此记录。

       如果您看了感觉或者曾经有更好的方法,烦请通知我一下,咱们能够独特探讨,如果有中央不对,也请不吝斧正。

遇到的问题

       因为不同性能的Job很多,每一个Job中都要实现对产生异样的音讯发送,现有的Job是这样的

       为了实现这个需要,也为了当前更好的保护,我筹备用事件委托的模式去实现,将对异样音讯发送的业务逻辑拆出,保障职责繁多,思路如下:

    1. 在Job和IJob两头再加一层IExceptionJobHandler接口作为束缚    2. 接口中定义一个发送异样音讯的事件PushException    3. 而后每一个Job在异样时去触发这个事件,内部只须要对立订阅一个事件即可。

       到目前这一步是可行的,尽管不是很完满的设计,然而还是比拟清晰的,然而另外一个问题来了,我如何通过Autofac注入这个Job呢,原来间接继承自Ijob当初加了一层。

问题剖析

       这个问题花了我整整大概4个小时的工夫去钻研依赖注入的形式还在网上搜了良久,没什么停顿,而后从新梳理了一下框架依赖注入的代码,发现是走错路了,注入Job应用的是Autofac.Extras.Quartz来实现的,这下晓得方向了。

 var builder = new ContainerBuilder(); builder.RegisterModule(new QuartzAutofacFactoryModule {     ConfigurationProvider = c => schedulerConfig });

       这个QuartzAutofacFactoryModule外面肯定有我想晓得的货色,就在Github上下载了Autofac.Extras.Quartz的源码,关上一看,果然发现了它的真面目

       这外面就是对Job依赖注入的,然而没有发现对Job的注册和构建,留神箭头标记的,它有一个AutofacJobFactory类,接管一个ILifetimeScope,而它的作用就是用来构建Job为作用域周期失效的服务实例。

解决的方法

  •        1.下面以及剖析出构建Job服务实例的,是一个叫AutofacJobFactory的工厂,返回一个IJob,那如何把IExceptionJobHandler注入进去,让咱们Job实例领有这个事件呢?
  •        2.因为咱们的IExceptionJobHandler曾经继承了IJob,也就是说这里间接能够把Ijob换成IExceptionJobHandler,那该如何实现呢?

继承

  •        3.咱们察看到在AutofacJobFactory构建服务的办法是一个虚办法,所以利用继承咱们新建一个ExtendAutofacJobFactory来重写它将Ijob换成IExceptionJobHandler
public class ExtendAutofacJobFactory : AutofacJobFactory  {     protected override IJob ResolveJobInstance(ILifetimeScope nestedScope, IJobDetail jobDetail)       {            //验证Job是否派生自IExceptionJobHandler            if (typeof(IExceptionJobHandler).IsAssignableFrom(jobDetail.JobType))            {                IExceptionJobHandler instance = null;                instance = (IExceptionJobHandler)CreateIJob(nestedScope, jobDetail);                //注册事件对立解决入口                instance.PushException += pushExceptionMessageManager.Value.ExceptionJobHandler                    return instance;            }            else            {                return base.ResolveJobInstance(nestedScope, jobDetail);            }       }  }
  •        4.咱们须要把重写的结构工厂放入QuartzAutofacFactoryModule,仍然抉择继承的形式去重写QuartzAutofacFactoryModule,而后在加载服务时将服务结构工厂换成咱们本人的ExtendAutofacJobFactory

  •        5. 在Autofac注册服务中央将QuartzAutofacFactoryModule改为ExtendQuartzAutofacFactoryModule,至此实现了自定义注入。
builder.RegisterModule(new ExtendQuartzAutofacFactoryModule{    ConfigurationProvider = c => schedulerConfig});