HangfireIO / Hangfire

An easy way to perform background job processing in .NET and .NET Core applications. No Windows Service or separate process required
https://www.hangfire.io
Other
9.35k stars 1.69k forks source link

Multiple injection of the same interface problem #2013

Open GBonkain opened 2 years ago

GBonkain commented 2 years ago

I have multiple injection of the same interface IBootOptions in my project to get the different options for the recurring jobs where we can set an Action called LongRunningFunction

services.AddTransient<IBootOptions>(s => new BootOptions
{
    LongRunningFunction = () => s.GetService<IMyService>().RetrieveTitleList()
});

services.AddTransient<IBootOptions>(s => new BootOptions
{
    LongRunningFunction = () => s.GetService<IMyService>().RetrieveSubTitleList()
});

I got a class Bootable that implement a method that will execute the LongRunningFunction when the recurring job are triggered

public  class Bootable : IBootable
{
    public Bootable(IBootOptions bootOptions)
    {
        BootOptions = bootOptions;
    }

    public void Execute()
    {
        BootOptions.LongRunningFunction();
    }
}

and finally in the startups, I declare all the recurring job

public void Configure(IServiceProvider serviceProvider)
{

    foreach (var bootOptions in serviceProvider.GetServices<IBootOptions>())
                recurringJobManager.AddOrUpdate(bootOptions.Job.Identity,
                    () => new Bootable(serviceProvider.GetService<IAuditLogEntryProvider>(),
                        serviceProvider.GetService<IAuditLogAdapter>(), bootOptions).Execute(), bootOptions.Job.CronSchedule);
}

My problem is that when the recurring job are triggered, the bootOptions is always the last injected bootOptions. So in my example the LongRunningFunction RetrieveSubTitleList will be executed two times and the RetrieveTitleList will never be executed. Hangfire recreate the Bootable object when it is triggered and the injected bootOptions is always the last. Is there a way to avoid hangfire to recreate the Bootable object when the recurring jobs are triggered ?

ergisgjergji commented 2 years ago

How is this a concern of Hangfire?

This is just DI 101 stuff. It's not even a real 'problem', it's just HOW you have 'architected' your code. You have 1 interface w/ multiple implementations, but in the Bootable class you are not being explicit as to which specific implementation to retrieve, thus it provides the most recent registration (which is the one with the RetrieveSubTitleList in your case).

So, it's not a 'problem', it's just the expected behaviour. If you want to instantiate Bootable with different IBootOptions dependencies, you have to refactor the Bootable class so that you can pass to it some kind of parameter to tell it which exact implementation of IBootOptions you want.

Here is a helpful article: Using dependency injection with multiple implementations of an interface in ASP.NET Core.


I suggest closure of this thread, as it is not a real 'issue' related to Hangfire.