Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coravel Background Service #317

Open
DLarner opened this issue Dec 3, 2022 · 9 comments
Open

Coravel Background Service #317

DLarner opened this issue Dec 3, 2022 · 9 comments

Comments

@DLarner
Copy link

DLarner commented Dec 3, 2022

Hi, I have implemented Coravel quite successfully and is working great. I have a couple of issues which is probably something I'm not doing right. My code is below. The queries are:

  1. The OnError is not working, this line is not being called when starting the application so therefore any errors are not captured by this global error routine. Can you see why?
  2. I have commented out the following line and the task still runs. Would you expect this? The reason why I have commented this line out is that it was causing an error:
    Message=Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: PricingUpdateController Lifetime: Transient ImplementationType: PricingUpdateController': Unable to resolve service for type 'System.Boolean' while attempting to activate 'PricingUpdateController'.)

Any help or guidance would be appreciated. Thanks and here is my relevant code:

IHost host = Host.CreateDefaultBuilder(args)
    .ConfigureLogging(
       loggingBuilder =>
       {
           var configuration = new ConfigurationBuilder()
                   .AddJsonFile("appsettings.json")
                   .Build();
       })
    .ConfigureServices(services =>
    {
        services.AddSingleton(new CommandLineArgs() { Args = args });
        services.AddHostedService<Worker>();
        services.AddApplicationInsightsTelemetryWorkerService();
        services.AddScheduler();
        //services.AddTransient<PricingUpdateController>();
    })
    .Build();

host.Services.UseScheduler(scheduler =>
{
    scheduler.ScheduleWithParams<PricingUpdateController>(false, false, false, true, true, true, false, false).EveryThirtySeconds().PreventOverlapping("PricingUpdateController");
})
.OnError(exception => LogController.Instance.LogText(exception.Message));

await host.RunAsync();
@jamesmh
Copy link
Owner

jamesmh commented Dec 4, 2022

So I'd uncomment the line with //services.AddTransient<PricingUpdateController>();.

The original exception you were getting Error while validating the service descriptor... means that the constructor of your PricingUpdateController has a mismatch with the parameter you supplied (e.g. the 8 booleans - does your PricingUpdateController class have a constructor with exactly 8 booleans?)

If you need more help could you past the constructor method signatures (not the body) for the PricingUpdateController class?

Thanks!

@DLarner
Copy link
Author

DLarner commented Dec 4, 2022 via email

@jamesmh
Copy link
Owner

jamesmh commented Dec 4, 2022

For fun, try making the class public instead of internal? Let me know what happens 🤔

@DLarner
Copy link
Author

DLarner commented Dec 4, 2022 via email

@jamesmh
Copy link
Owner

jamesmh commented Dec 4, 2022

So I can confirm your first comments - commenting out the //services.AddTransient<PricingUpdateController>(); makes this work. Otherwise, something is amiss...

I tried adding some unit tests in the main project against this case - and they pass. Yet, when I create a new real-life .NET project similar to yours, then I am getting the same exception lol.

And you are correct that this is not expected behaviour. This happens with other constructor types like integers, strings, etc. And also only when one param is present.

I suspect this is something to do with .NET 7 or some new DI stuff that Microsoft changed under the covers (not the first time this happened!)

I'll look into this - but for now just don't register the invocable and it seems like it works 🤔

@DLarner
Copy link
Author

DLarner commented Dec 4, 2022 via email

@jamesmh
Copy link
Owner

jamesmh commented Dec 4, 2022

For OnError -> try throwing an exception from inside your invocable's Invoke method. It should trigger.

@DLarner
Copy link
Author

DLarner commented Dec 4, 2022 via email

@esskar
Copy link

esskar commented Mar 2, 2023

What happens if you update your controller like

public record PricingUpdateControllerConfiguration(
    bool TestSystem;
    bool CalculateStones;
    bool CalculateProducts;
    bool CalculateMetals;
    bool CalculateProductGroupMounts;
    bool CalculateOrders;
    bool CalculateInvoices;
    bool CheckStockAvailable);

public class PricingUpdateController : IInvocable
{
    private readonly PricingUpdateControllerConfiguration _configuration;

    public PricingUpdateController(PricingUpdateControllerConfiguration configuration)
    {
         _configuration = cofiguration;
    }
     
    // ...
}

and call it with

host.Services.UseScheduler(scheduler =>
{
    scheduler.ScheduleWithParams<PricingUpdateController>(
        new PricingUpdateControllerConfiguration(false, false, false, true, true, true, false, false)
    ).EveryThirtySeconds().PreventOverlapping(nameof(PricingUpdateController));
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants