关于 hangfire 初始化工作机制


hangfire初始化的配置方法 :UseHangfire 。

   public static class OwinBootstrapper
    {
        /// <summary>
        /// Bootstraps Hangfire components using the given configuration
        /// action and maps Hangfire Dashboard to the app builder pipeline
        /// at the configured path ('/hangfire' by default).
        /// </summary>
        /// <param name="app">The app builder</param>
        /// <param name="configurationAction">Configuration action</param>
        public static void UseHangfire([NotNull] this IAppBuilder app,[NotNull] Action<IBootstrapperConfiguration> configurationAction)
        {
            if (app == null) throw new ArgumentNullException("app");
            if (configurationAction == null) throw new ArgumentNullException("configurationAction");
            // 初始化配置,给了默认值
            var configuration = new BootstrapperConfiguration(); 
            // 委托  赋值
            configurationAction(configuration);

            if (configuration.Activator != null)
            {
                JobActivator.Current = configuration.Activator;
            }

            if (configuration.Storage == null)
            {
                throw new InvalidOperationException("Job storage was not configured. Please call either `UseStorage` method or its overloads.");
            }
            // 获取当前的存储方式
            JobStorage.Current = configuration.Storage;
            // 通过UseFilter()将配置的过滤器放入容器中
            foreach (var filter in configuration.Filters)
            {
                GlobalJobFilters.Filters.Add(filter);
            }
            // 通过UseServers()将配置的过滤器放入容器中 ,如果需要分布式配置的话,在客户端就不要配置server
            foreach (var server in configuration.Servers)
            {
                app.RunHangfireServer(server());
            }
            // 将Route和权限filter注入到owin管道中
            app.MapHangfireDashboard(configuration.DashboardPath, configuration.AuthorizationFilters);
        }
    }

用委托的方式来处理而不是让开发人员自己去实现IBootstrapperConfiguration接口

这种方式确实开发人员使用上更方便了。 


      public static void MapHangfireDashboard(
            [NotNull] this IAppBuilder app,
            string dashboardPath,
            IEnumerable<IAuthorizationFilter> authorizationFilters,
            JobStorage storage)
        {
            if (app == null) throw new ArgumentNullException("app");

            SignatureConversions.AddConversions(app);

            app.Map(dashboardPath,subApp => subApp.Use<DashboardMiddleware>(
                storage,
                DashboardRoutes.Routes,
                authorizationFilters));
        }
MapHangfireDashboard方法是将DashboardMiddleware注册到own管道中

dashboardPath默认值是“/hangfire”  ,也就是说当你通过 Http://www.xxx.com/hangfire 访问的每个请求都会进入DashboardMiddleware

DashboardMiddleware继承了OwinMiddleware
 // 方法在DashboardMiddleware内

        public override Task Invoke(IOwinContext context)
        {
            // RouteCollection 是路由规则集合,
            var dispatcher = _routes.FindDispatcher(context.Request.Path.Value);
            
            if (dispatcher == null)
            {
                // 下一个OwinMiddleware中去处理
                // 一个请求会有多个OwinMiddleware
                return Next.Invoke(context);
            }
             
            foreach (var filter in _authorizationFilters)
            {
                if (!filter.Authorize(context.Environment))
                {
                    context.Response.StatusCode = (int) HttpStatusCode.Unauthorized;
                    return Task.FromResult(false);
                }
            }
            
            // 输出内容
            var dispatcherContext = new RequestDispatcherContext(
                _storage,
                context.Environment,
                dispatcher.Item2);
            
            return dispatcher.Item1.Dispatch(dispatcherContext);
        }

RequestDispatcherContext 内部调度实现相对有些复杂,暂时没时间去研究,我机会再分享了。
 
原文地址:https://www.cnblogs.com/yuanhuaming/p/4384429.html