Single Dashboard, Single Physical Server, Multiple Jobs/Projects/Codebases. Advice or Examples?

Alright, I think I’ve gotten everything figured out. Here’s my “shared dashboard for dummies: visual studio edition” guide. It assumes you’ve already got a separate project running the Hangfire dashboard (and optionally, serving its own jobs on its own queue).

  • Make a new Visual Studio ASP.NET project with the blank template
  1. Install the NuGet packages Hangfire and Hangfire.Autofac

  2. Add a new C# class using the template “Owin Startup Class”, which we usually name Startup.cs
    In the Configuration method, add the lines:

             public void Configuration(IAppBuilder app)
             {
                 //Build Autofac IoC container
                 var builder = new ContainerBuilder();
                 //Link our jobs interface to its implementation
                 builder.RegisterType<Job>().As<IExampleHangfireJob>().AsImplementedInterfaces().InstancePerBackgroundJob();
                 var container = builder.Build();
                 GlobalConfiguration.Configuration
                     .UseSqlServerStorage("DefaultConnection") //The connection string for our hangfire database, defined in web.config
                     .UseAutofacActivator(container);
                 //This server only processes jobs from this queue
                 app.UseHangfireServer(new BackgroundJobServerOptions() { Queues = new string[] { "example_queue" } });
                 //Autofac will instantiate the class implementing this interface. The dashboard knows about the interface and can thus display the job properly.
                 BackgroundJob.Enqueue<IExampleHangfireJob>((x) => x.DoSomething());
    
  • Write the interface defining the job. Make this a separate VS project so you can easily build it as a DLL. This project should also include the Hangfire nuget package (because of the queue attribute). Just create a standard class library with one file, IExampleHangfireJob.cs, containing the following:

          public interface IExampleHangfireJob
          {
              [Queue("example_queue")] //Specifies that the job only runs on this server's queue. The queue attribute must be in the interface, not the implementation.
              void DoSomething();
          }
    
  • Now write the actual implementation for the job. This can be in the same Visual Studio project containing Startup.cs. Create a Job class implementing IExampleHangfireJob, and give it a public DoSomething() method, wherein the job actually performs its tasks.

    • The DoSomething() method can accept arguments, which will be serialized for the database. Keep in mind that if these arguments are custom types/classes, the dashboard will also need to know about them!
    • Important: Queue names can only contain lowercase letters, underscores, and numbers!

Build the interface dll and add it as a reference to the dashboard project. You could also make the interface a shared assembly and add it to the Global Assembly Cache on the machine running the dashboard, if you don’t want to recompile the dashboard project.

I think another valid, and possibly easier, approach would be to have a single web application acting as dashboard, client, and server, then compile all your jobs as assemblies referenced by said project. You wouldn’t need to bother with interfaces, queues, or IoC containers, but you would also be forced to run all your jobs from the same physical machine and you’d probably be recompiling the web app frequently.

1 Like