一、官方描述

These projects simplify the integration between Hangfire and your favorite IoC Container. They provide custom implementation of JobActivator class as well as registration extensions that allow you to use unit of work pattern or deterministic disposal in your background jobs.

根据上述说明可以简单理解为继承“JobActivator”来实现自定义IOC容器。

二、JobActivator


  1. //抽象Job生命周期
  2. public abstract class JobActivatorScope : IDisposable
  3. {
  4. ....省略
  5. //定义抽象方法,获取实例
  6. public abstract object Resolve(Type type);
  7. //定义虚方法,摧毁生命周期
  8. public virtual void DisposeScope()
  9. {
  10. }
  11. }
  12. public class JobActivator
  13. {
  14. ....省略
  15. //定义虚方法,默认使用反射获取实例
  16. public virtual object ActivateJob(Type jobType)
  17. {
  18. return Activator.CreateInstance(jobType);
  19. }
  20. //定义虚方法,创建一个生命周期
  21. [Obsolete("Please implement/use the BeginScope(JobActivatorContext) method instead. Will be removed in 2.0.0.")]
  22. public virtual JobActivatorScope BeginScope()
  23. {
  24. return new SimpleJobActivatorScope(this);
  25. }
  26. //定义虚方法,创建一个生命周期
  27. public virtual JobActivatorScope BeginScope(JobActivatorContext context)
  28. {
  29. #pragma warning disable 618
  30. return BeginScope();
  31. #pragma warning restore 618
  32. }
  33. //实现简单的生命周期
  34. class SimpleJobActivatorScope : JobActivatorScope
  35. {
  36. private readonly JobActivator _activator;
  37. //存储所有需要回收的实例
  38. private readonly List<IDisposable> _disposables = new List<IDisposable>();
  39. public SimpleJobActivatorScope([NotNull] JobActivator activator)
  40. {
  41. if (activator == null) throw new ArgumentNullException(nameof(activator));
  42. _activator = activator;
  43. }
  44. public override object Resolve(Type type)
  45. {
  46. var instance = _activator.ActivateJob(type);
  47. var disposable = instance as IDisposable;
  48. if (disposable != null)
  49. {
  50. _disposables.Add(disposable);
  51. }
  52. return instance;
  53. }
  54. public override void DisposeScope()
  55. {
  56. foreach (var disposable in _disposables)
  57. {
  58. disposable.Dispose();
  59. }
  60. }
  61. }
  62. }

三、.Net Core 原生DI作为IOC容器

Hangfire.AspNetCore源码实现

  1. public class AspNetCoreJobActivator : JobActivator
  2. {
  3. private readonly IServiceScopeFactory _serviceScopeFactory;
  4. ....省略
  5. public override JobActivatorScope BeginScope(JobActivatorContext context)
  6. {
  7. return new AspNetCoreJobActivatorScope(_serviceScopeFactory.CreateScope());
  8. }
  9. #pragma warning disable CS0672 // Member overrides obsolete member
  10. public override JobActivatorScope BeginScope()
  11. #pragma warning restore CS0672 // Member overrides obsolete member
  12. {
  13. return new AspNetCoreJobActivatorScope(_serviceScopeFactory.CreateScope());
  14. }
  15. }
  16. internal class AspNetCoreJobActivatorScope : JobActivatorScope
  17. {
  18. private readonly IServiceScope _serviceScope;
  19. ....省略
  20. public override object Resolve(Type type)
  21. {
  22. //注意:AspNetCore是获取或者创建,意味着实例没有注入也会创建一个新的实例
  23. return ActivatorUtilities.GetServiceOrCreateInstance(_serviceScope.ServiceProvider, type);
  24. }
  25. public override void DisposeScope()
  26. {
  27. _serviceScope.Dispose();
  28. }
  29. }

四、Autofac 作为IOC容器

Hangfire.Autofac源码实现

  1. /// <summary>
  2. /// Hangfire Job Activator based on Autofac IoC Container.
  3. /// </summary>
  4. public class AutofacJobActivator : JobActivator
  5. {
  6. /// <summary>
  7. /// Tag used in setting up per-job lifetime scope registrations.
  8. /// </summary>
  9. public static readonly object LifetimeScopeTag = "BackgroundJobScope";
  10. private readonly ILifetimeScope _lifetimeScope;
  11. private readonly bool _useTaggedLifetimeScope;
  12. ....省略
  13. //重写
  14. public override object ActivateJob(Type jobType)
  15. {
  16. return _lifetimeScope.Resolve(jobType);
  17. }
  18. #if NET45
  19. //重写
  20. public override JobActivatorScope BeginScope()
  21. {
  22. return new AutofacScope(_useTaggedLifetimeScope
  23. ? _lifetimeScope.BeginLifetimeScope(LifetimeScopeTag)
  24. : _lifetimeScope.BeginLifetimeScope());
  25. }
  26. #else
  27. //重写
  28. public override JobActivatorScope BeginScope(JobActivatorContext context)
  29. {
  30. return new AutofacScope(_useTaggedLifetimeScope
  31. ? _lifetimeScope.BeginLifetimeScope(LifetimeScopeTag)
  32. : _lifetimeScope.BeginLifetimeScope());
  33. }
  34. #endif
  35. class AutofacScope : JobActivatorScope
  36. {
  37. private readonly ILifetimeScope _lifetimeScope;
  38. ....省略
  39. //重写
  40. public override object Resolve(Type type)
  41. {
  42. return _lifetimeScope.Resolve(type);
  43. }
  44. //重写
  45. public override void DisposeScope()
  46. {
  47. _lifetimeScope.Dispose();
  48. }
  49. }
  50. }

五、使用

在Hangfire源码“CoreBackgroundJobPerformer”类中使用:

  1. //执行任务
  2. public object Perform(PerformContext context)
  3. {
  4. //创建一个生命周期
  5. using (var scope = _activator.BeginScope(
  6. new JobActivatorContext(context.Connection, context.BackgroundJob, context.CancellationToken)))
  7. {
  8. object instance = null;
  9. ....省略
  10. //任务是否为静态方法,若是静态方法需要从IOC容器中取出实例
  11. if (!context.BackgroundJob.Job.Method.IsStatic)
  12. {
  13. instance = scope.Resolve(context.BackgroundJob.Job.Type);
  14. ....省略
  15. }
  16. ....省略
  17. }
  18. }

Hangfire源码解析-如何实现可扩展IOC的?的更多相关文章

  1. Spring源码解析 | 第二篇:Spring IOC容器之XmlBeanFactory启动流程分析和源码解析

    一. 前言 Spring容器主要分为两类BeanFactory和ApplicationContext,后者是基于前者的功能扩展,也就是一个基础容器和一个高级容器的区别.本篇就以BeanFactory基 ...

  2. Hangfire源码解析-任务是如何执行的?

    一.Hangfire任务执行的流程 任务创建时: 将任务转换为Type并存储(如:HangFireWebTest.TestTask, HangFireWebTest, Version=1.0.0.0, ...

  3. 1、Dubbo源码解析--Dubbo如何驱动Spring IOC容器并配合工作的?

    首先Spring要注入自己的bean需要在Spring-provider.xml(提供者spring注入文件,名字可能不一样)添加bean注入,其中有dubbo的自定义标签,xml如何识别这些标签?拿 ...

  4. 设置ZooKeeper服务器地址列表源码解析及扩展

    设置ZooKeeper服务器地址列表源码解析及扩展 ZooKeeper zooKeeper = new ZooKeeper("192.168.109.130:2181",SESSI ...

  5. jQuery2.x源码解析(设计篇)

    jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 这一篇笔者主要以设计的角度探索jQuery的源代 ...

  6. jQuery2.x源码解析(回调篇)

    jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 通过艾伦的博客,我们能看出,jQuery的pro ...

  7. 小学徒成长系列—StringBuilder & StringBuffer关键源码解析

    在前面的博文<小学徒成长系列—String关键源码解析>和<小学徒进阶系列—JVM对String的处理>中,我们讲到了关于String的常用方法以及JVM对字符串常量Strin ...

  8. jQuery整体架构源码解析(转载)

    jQuery整体架构源码解析 最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性, ...

  9. JQuery源码解析(一)

    写在前面:本<JQuery源码解析>系列是基于一些前辈们的文章进行进一步的分析.细化.修改而写出来的,在这边感谢那些慷慨提供科普文档的技术大拿们. 要查阅JQ的源文件请下载开发版的JQ.j ...

随机推荐

  1. Python Web 框架:Tornado

    1.Tornado Tornado:python编写的web服务器兼web应用框架 1.1.Tornado的优势 轻量级web框架 异步非阻塞IO处理方式 出色的抗负载能力 优异的处理性能,不依赖多进 ...

  2. Centos7下安装PHP5.5,5.6,7.0----(转载记录一下)

    由于centOS7 默认的php版本是5.4的,偏低,所以收录了一下怎样安装5.5/5.6/7.0版本 默认的版本太低了,手动安装有一些麻烦,想采用Yum安装的可以使用下面的方案: 1.检查当前安装的 ...

  3. OpenGL渲染管线(rendering pipeline)

    OpenGL中的渲染管线包括:顶点着色器(vertex shader).细分着色器(里面包含两种:细分控制着色器和细分控制着色器)(tessellation shader).几何着色器.光栅化及片元着 ...

  4. python环境下实现OrangePi Zero寄存器访问及GPIO控制

    最近入手OrangePi Zero一块,程序上需要使用板子上自带的LED灯,在网上一查,不得不说OPi的支持跟树莓派无法相比.自己摸索了一下,实现简单的GPIO控制方法,作者的Zero安装的是Armb ...

  5. XML错误信息Referenced file contains errors (http://www.springframework.org/schema/beans/spring-beans-4.0.xsd). For more information, right click on the message in the Problems View ...

    错误信息:Referenced file contains errors (http://www.springframework.org/schema/beans/spring-beans-4.0.x ...

  6. TCP报文解析

    概述 在<网络基础总结(一)>总结了TCP建立连接和断开连接的流程,然而TCP协议远比我所了解的复杂得多,我所知的可以说就冰山一角,所总结的也只是纸上谈兵,仅仅只能对TCP有个肤浅的认识, ...

  7. redis测试实践

    最近测试服务端的时候,接触到了redis,之前也看过,但不系统,借着这次实践,记录一下. 一.写在前面 Redis是一个开源的使用ANSI C语言编写.遵守BSD协议.支持网络.可基于内存亦可持久化的 ...

  8. 轻量级原生 ajax 函数,支持 get/array post/array post/json

    原生js封装 function ajaxRequest(type, url, data, callback, failCallBack, header, dataType) { var url_enc ...

  9. Aria2序之导言

    aria2是什么,如果此时此刻你看到标题读到第一行正在思索着一个问题,很抱歉 ,这篇以及后续我的blog不适合你,请移步. 我在aria2的官方站点抄袭了如下语句用来充实本文: aria2 is a  ...

  10. 驰骋工作流引擎 -Webservice接口说明文档

      关键词:工作流引擎接口说明  驰骋工作流接口参数详解 接口 LocalWSI /** * 待办 * @param userNo 用户编号 * @param sysNo 系统编号,为空时返回平台所有 ...