一、官方描述

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 源码解析 之 setContentView

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/41894125,本文出自:[张鸿洋的博客] 大家在平时的开发中,对于setCont ...

  2. 读取txt内文件内容

    命令如下: f = open("c:\\1.txt","r")  lines = f.readlines()#读取全部内容  for line in lines ...

  3. 搞定! iTunes 不能添加铃声进去

    最近换个新铃声,但转换成.m4r 怎么都拖不到铃声里很莫名奇妙,首先确定苹果是允许自己定义铃声的,然后网上查了不少文章,都无济于事所以我想自己记录下自己成功搞定的方法,供各位参考第一步: 把自己想转为 ...

  4. appium 常用API使用总结!

    将常用函数进行适用总结,后期在使用的过程中直接查找调用即可 获取界面属性.控件属性 1.current_activity:获取activity名称 device.current_activity 2. ...

  5. 原型模式--java代码实现

    原型模式 原型模式,属于对象创建型模式中的一种.通过复制原型对象的方法来创建一个对象实例,且该对象与原对象有相同的数据结构和值.类似我们在备份数据库信息的时候,将数据库中表的结构和数据的一同备份,生成 ...

  6. MIP 技术交流分享(3月15日)

    3月15日下午,MIP 团队工程师与58赶集的 Web 前端工程师进行了一次面对面的技术交流. 在这次交流中,MIP 工程师主要分享了 MIP 技术原理,MIP 加速原理,以及 MIP 为开发者提供的 ...

  7. typeconfig.json配置说明

    如果一个目录下存在一个tsconfig.json文件,那么它意味着这个目录是TypeScript项目的根目录. 不带任何输入文件的情况下调用tsc,编译器会从当前目录开始去查找tsconfig.jso ...

  8. JavaWeb 乱码问题终极解决方案!

    经常有读者在公众号上问 JavaWeb 乱码的问题,昨天又有一个小伙伴问及此事,其实这个问题很简单,但是想要说清楚却并不容易,因为每个人乱码的原因都不一样,给每位小伙伴都把乱码的原因讲一遍也挺费时间的 ...

  9. Hadoop HA高可用集群搭建(Hadoop+Zookeeper+HBase)

    声明:作者原创,转载注明出处. 作者:帅气陈吃苹果 一.服务器环境 主机名 IP 用户名 密码 安装目录 master188 192.168.29.188 hadoop hadoop /home/ha ...

  10. 老司机心得之时间管理"入坑"

    长期以来,时间管理一直被认为是自我管理,团队管理,项目管理的既关键又基础的手段,就连笔者本人也一直在崇尚时间管理的理念. 但是这里要讲的,不是什么鬼神方法论.而主要是对长时间以来学习和实践时间管理的一 ...