Hangfire源码解析-如何实现可扩展IOC的?

一、官方描述

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);

            ....省略
        }
        ....省略
    }
}

转载于:https://www.cnblogs.com/yrinleung/p/10554322.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值