Hangfire.MissionControl icon indicating copy to clipboard operation
Hangfire.MissionControl copied to clipboard

Customize parameter handling

Open KorsG opened this issue 1 year ago • 4 comments

Hi and thank you for a great project first of all!

We have some jobs with specialized parameters that needs to be handled the same way as e.g. PerformContext and CancellationToken so they are not required to invoke the mission (they are instantiated by the Hangfire pipeline), but that is not customizable in the current version.

It seems to be handled by the following internal static classes:

  1. MissionParameterParser: https://github.com/ahydrax/Hangfire.MissionControl/blob/master/src/Hangfire.MissionControl/Launching/MissionParameterParser.cs
  2. ControlFactory: https://github.com/ahydrax/Hangfire.MissionControl/blob/master/src/Hangfire.MissionControl/Dashboard/Pages/Controls/ControlFactory.cs

Would you be willing to consider adding such functionality to the project?

If you dont mind, I can probably do a pull-request with a suggested approach at some point. Currently I am thinking about adding a Func to the MissionControlOptions class to support adding custom mappings of MissionParameters and RazorPage controls based on the type. That would probably require some refactoring's though.

KorsG avatar Nov 08 '23 13:11 KorsG

Hi @KorsG. Not sure if I understood correct but why you couldn't use dependency injection through mission constructor? Could you show a code example where it doesn't work via DI?

ahydrax avatar Nov 09 '23 05:11 ahydrax

Hi @ahydrax

Thats a fair question - I have customized Hangfire to allow custom parameter injection in the Hangfire pipeline, besides the standard support for CancellationToken etc.

I e.g have a type called JobExecutionContext that works a little bit like the PerformContext and it is constructed by the Hangfire pipeline during runtime and passed to any method that has it as an argument:

// I would like to able to use this as a mission, but cant because of the custom JobExecutionContext parameter,
// that is instantiated in the Hangfire pipeline
[AutomaticRetry()]
public void SomeJob(int firmNo, JobExecutionContext executionContext = default, CancellationToken cancellationToken = default)
{
}

Technically I could probably make the types that I use work with DI in the constructors, like with PerformContext, but I think parameter injection is much cleaner to work with:

internal class SomeClass
{
    private readonly JobExecutionContext _executionContext;

    public SomeClass(JobExecutionContext executionContext)
    {
        _executionContext = executionContext;
    }

    [AutomaticRetry()]
    public void SomeJob(int firmNo, CancellationToken cancellationToken = default)
    {
        // _executionContext.Work()
    }
}

Hope that makes sense :-)

KorsG avatar Nov 09 '23 18:11 KorsG

Is JobExecutionContext something that Hangfire provides as part of library? Do you want to inject only Hangfire built-in types like that?

ahydrax avatar Nov 10 '23 12:11 ahydrax

It's a custom type, so I would like to be able to add custom types that is not part of the core Hangfire library.

Alternatively if I could add it as an "ignored" type, that would also solve my issue, because these types should never be provided by the user. E.g. as a static collection of types on the MissionControlOptions:

[PublicAPI]
public sealed class MissionControlOptions
{
    public bool RequireConfirmation { get; set; }
    public bool HideCodeSnippet { get; set; }
    // Example:
    public static List<Type> IgnoreTypesAsParameters { get; set; }
}

Then this could be checked in the current MissionParameterParser and ControlFactory without changing much, and handled in the same way as e.g. PerformContext by return NullControl() etc.

That would be a much simpler solution, although not as flexible but that's probably not required anyways :-)

KorsG avatar Nov 13 '23 15:11 KorsG