一、官方描述

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 实现形态各异的双向侧滑菜单 自定义控件来袭

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/39670935,本文出自:[张鸿洋的博客] 1.概述 关于自定义控件侧滑已经写了两 ...

  2. 把List<string>集合,编程string,并以“,”号分割

    List<int> roleIdList = GetRoleIdList(user.ID); string roleIdsStr = ""; if (roleIdLis ...

  3. BZOJ_1408_[Noi2002]Robot_数学

    Description Input Output Sample Input 3 2 1 3 2 5 1 Sample Output 8 6 75 HINT 90号机器人有10个老师,加上它自己共11个 ...

  4. jdk源码剖析一:OpenJDK-Hotspot源码包目录结构

    开启正文之前,先说一下源码剖析这一系列,就以“死磕到底”的精神贯彻始终,JDK-->JRE-->JVM(以openJDK代替) 最近想看看JDK8源码,但JDK中JVM(安装在本地C:\P ...

  5. 使用limit查询的同时取得总的记录数:SQL_CALC_FOUND_ROWS和FOUND_ROWS()

    通常我们都用如下的sql来进行列表 SELECT COUNT(*) FROM users WHERE name LIKE 'a%';SELECT name, email FROM users WHER ...

  6. Uiautomator分类

    分类中主要使用的类介绍!

  7. JAVAEE——SpringMVC第一天:介绍、入门程序、架构讲解、SpringMVC整合MyBatis、参数绑定、SpringMVC和Struts2的区别

    1. 学习计划   第一天 1.SpringMVC介绍 2.入门程序 3.SpringMVC架构讲解 a) 框架结构 b) 组件说明 4.SpringMVC整合MyBatis 5.参数绑定 a) Sp ...

  8. 响应式编程知多少 | Rx.NET 了解下

    1. 引言 An API for asynchronous programming with observable streams. ReactiveX is a combination of the ...

  9. 安卓开发笔记(三十):自定义Button

    在笔者本人看了很多博客和书之后,发现很少博主对于自定义控件能够进行一个比较全面的思路讲解,大多数都是只讲了一些细节,但并没有讲如何把代码进行整体的实现.因此这里讲讲整体的自定义button实现的详细过 ...

  10. 自学java能不能找到找到一份java工作。

    关于自学Java能不能通过社招找到一份互联网公司Java开发的工作,有无数的人问出这样的问题,答案没有标准的,只能从概率去考虑.有的人可以,有的人不可以,有的人自学就业的概率就是高,有的概率就是低. ...