一、官方描述

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


//抽象Job生命周期
public abstract class JobActivatorScope : IDisposable
{
....省略
//定义抽象方法,获取实例
public abstract object Resolve(Type type);
//定义虚方法,摧毁生命周期
public virtual void DisposeScope()
{
} } public class JobActivator
{
....省略 //定义虚方法,默认使用反射获取实例
public virtual object ActivateJob(Type jobType)
{
return Activator.CreateInstance(jobType);
} //定义虚方法,创建一个生命周期
[Obsolete("Please implement/use the BeginScope(JobActivatorContext) method instead. Will be removed in 2.0.0.")]
public virtual JobActivatorScope BeginScope()
{
return new SimpleJobActivatorScope(this);
} //定义虚方法,创建一个生命周期
public virtual JobActivatorScope BeginScope(JobActivatorContext context)
{
#pragma warning disable 618
return BeginScope();
#pragma warning restore 618
} //实现简单的生命周期
class SimpleJobActivatorScope : JobActivatorScope
{
private readonly JobActivator _activator;
//存储所有需要回收的实例
private readonly List<IDisposable> _disposables = new List<IDisposable>(); public SimpleJobActivatorScope([NotNull] JobActivator activator)
{
if (activator == null) throw new ArgumentNullException(nameof(activator));
_activator = activator;
} public override object Resolve(Type type)
{
var instance = _activator.ActivateJob(type);
var disposable = instance as IDisposable; if (disposable != null)
{
_disposables.Add(disposable);
} return instance;
} public override void DisposeScope()
{
foreach (var disposable in _disposables)
{
disposable.Dispose();
}
}
}
}

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

Hangfire.AspNetCore源码实现

public class AspNetCoreJobActivator : JobActivator
{
private readonly IServiceScopeFactory _serviceScopeFactory;
....省略 public override JobActivatorScope BeginScope(JobActivatorContext context)
{
return new AspNetCoreJobActivatorScope(_serviceScopeFactory.CreateScope());
} #pragma warning disable CS0672 // Member overrides obsolete member
public override JobActivatorScope BeginScope()
#pragma warning restore CS0672 // Member overrides obsolete member
{
return new AspNetCoreJobActivatorScope(_serviceScopeFactory.CreateScope());
}
} internal class AspNetCoreJobActivatorScope : JobActivatorScope
{
private readonly IServiceScope _serviceScope;
....省略 public override object Resolve(Type type)
{
//注意:AspNetCore是获取或者创建,意味着实例没有注入也会创建一个新的实例
return ActivatorUtilities.GetServiceOrCreateInstance(_serviceScope.ServiceProvider, type);
} public override void DisposeScope()
{
_serviceScope.Dispose();
}
}

四、Autofac 作为IOC容器

Hangfire.Autofac源码实现

/// <summary>
/// Hangfire Job Activator based on Autofac IoC Container.
/// </summary>
public class AutofacJobActivator : JobActivator
{
/// <summary>
/// Tag used in setting up per-job lifetime scope registrations.
/// </summary>
public static readonly object LifetimeScopeTag = "BackgroundJobScope"; private readonly ILifetimeScope _lifetimeScope;
private readonly bool _useTaggedLifetimeScope;
....省略 //重写
public override object ActivateJob(Type jobType)
{
return _lifetimeScope.Resolve(jobType);
} #if NET45
//重写
public override JobActivatorScope BeginScope()
{
return new AutofacScope(_useTaggedLifetimeScope
? _lifetimeScope.BeginLifetimeScope(LifetimeScopeTag)
: _lifetimeScope.BeginLifetimeScope());
}
#else
//重写
public override JobActivatorScope BeginScope(JobActivatorContext context)
{
return new AutofacScope(_useTaggedLifetimeScope
? _lifetimeScope.BeginLifetimeScope(LifetimeScopeTag)
: _lifetimeScope.BeginLifetimeScope());
}
#endif class AutofacScope : JobActivatorScope
{
private readonly ILifetimeScope _lifetimeScope;
....省略 //重写
public override object Resolve(Type type)
{
return _lifetimeScope.Resolve(type);
} //重写
public override void DisposeScope()
{
_lifetimeScope.Dispose();
}
}
}

五、使用

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

//执行任务
public object Perform(PerformContext context)
{
//创建一个生命周期
using (var scope = _activator.BeginScope(
new JobActivatorContext(context.Connection, context.BackgroundJob, context.CancellationToken)))
{
object instance = null;
....省略 //任务是否为静态方法,若是静态方法需要从IOC容器中取出实例
if (!context.BackgroundJob.Job.Method.IsStatic)
{
instance = scope.Resolve(context.BackgroundJob.Job.Type); ....省略
}
....省略
}
}

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. Android 自定义ViewGroup手把手教你实现ArcMenu

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/37567907 逛eoe发现这样的UI效果,感觉很不错,后来知道github上有这 ...

  2. Windows下Pytesser安装

    安装流程   详细步骤 安装PIL 32位机器:去到PIL官网进行安装 64位机器:建议使用Pillow代替PIL,PIL官网的安装包在64位机器下无法找到,安装Pillow也非常简单,使用pip就可 ...

  3. 简化异常处理的Throwables类

    简化异常处理的Throwables类 有时候, 当我们我们捕获异常, 并且像把这个异常传递到下一个try/catch块中.Guava提供了一个异常处理工具类, 可以简单地捕获和重新抛出多个异常.例如: ...

  4. 关于CocoaPods的ruby镜像文件问题

    项目遇到第三方库更新问题 时   用到cocoaPods更换淘宝ruby镜像问题的时候  报错 后来 又在别处找了下 发现 用的是 https  如下: 后来细想  可能跟Xcode7 要求HTTPs ...

  5. 电梯调度设计之初感想——蔡迎盈&&曹玉松

    突然拿到这个问题,蒙了好久,索性走一步,再走一步好了,希望在这天下第一庄里,会看到晴空.   查了好多资料,终于还是整理出一个很草稿的版本,这只能算是我们初步的设计.   四部电梯载重和乘客限制不同, ...

  6. shell的嵌入命令大全

    围绕以下几点展开学习: 1.什么是shell的嵌入命令? 2.为什么使用shell? 3.怎样使用shell嵌入命令? 1.什么是shell的嵌入命令: ♦这些命令是在实际的Bourne shell里 ...

  7. 贝叶斯深度学习(bayesian deep learning)

      本文简单介绍什么是贝叶斯深度学习(bayesian deep learning),贝叶斯深度学习如何用来预测,贝叶斯深度学习和深度学习有什么区别.对于贝叶斯深度学习如何训练,本文只能大致给个介绍. ...

  8. sum() 函数性能堪忧,列表降维有何良方?

    本文原创并首发于公众号[Python猫],未经授权,请勿转载. 原文地址:https://mp.weixin.qq.com/s/mK1nav2vKykZaKw_TY-rtw Python 的内置函数 ...

  9. Java8新特性之三:Stream API

    Java8的两个重大改变,一个是Lambda表达式,另一个就是本节要讲的Stream API表达式.Stream 是Java8中处理集合的关键抽象概念,它可以对集合进行非常复杂的查找.过滤.筛选等操作 ...

  10. SpringCloud学习系列之五-----配置中心(Config)和消息总线(Bus)完美使用版

    前言 在上篇中介绍了SpringCloud Config的使用,本篇则介绍基于SpringCloud(基于SpringBoot2.x,.SpringCloud Finchley版)中的分布式配置中心( ...