dependency-injectioninversion-of-controlioc-containerhangfirehangfire-autofac

Hangfire Register IoC Dependency in Scope For Job at Run Time


Issue: most jobs are dependent on configuration dependency.

Ideal Solution: (copied here and at end just to save reading if you already know exactly how to do this)

I would like to

Old Solution: for the custom "job scheduler" that I am replacing we take the following steps

Hack Solution: so this works for most but I still want to know how to accomplish what I am trying to do, by creating a "wrapper job" class that uses the same data to crate the same scope when running the job.

Ideal Solution: Ideally I can inject logic and

I have Tried / Looked Into Filter Attributes - works to save and restore data but have not found any access to IoC or lifetime scope here.

there were a few other options but they too were limited in "exposure" to the IoC container / scope

Ideal Solution: I would like to


Solution

  • wow I am dense, so looking over the [Delegate Factories](Delegate Factories) documentation and taking a deeper dive into Implicit Relationship Types

    I realized I was making this a lot harder than it needed to be and what I was looking for is clearly documented here but I never looked close enough so here is a working sample

    note:

    1. not all dependencies are required at runtime, Autofac fills in everything not provided by the func
    2. you do no need to configure or register anything special to create the Func<>, just add it to the constructor of your dependent class

    Sample:

      public class ScratchPad
      {
          [Fact]
          public void WhenRunningThisThenItWorks()
          {
              var builder = new ContainerBuilder();
              builder.RegisterType<MyNeedyRuntimeClass>();
              builder.RegisterType<SomethingElseNeeded>();
              var container = builder.Build();
    
              var theFuncFactory = container.Resolve<Func<SomeRuntimeThing, MyNeedyRuntimeClass>>();
              var func = () => theFuncFactory.Invoke(new SomeRuntimeThing());
              func.Should().NotThrow("constructor need for `SomeRuntimeThing` should be passed in from Func and dependency for `SomethingElseNeeded` is handled from the service registration");
          }
      }
    

    here are the empty classes I used just for ref

      class MyNeedyRuntimeClass
      {
          public MyNeedyRuntimeClass(SomeRuntimeThing someRuntimeIdOrSomething, SomethingElseNeeded bar)
          {
              //....
          }
      }
    
      internal class SomeRuntimeThing
      {
      }
    
      internal class SomethingElseNeeded
      {
      }