coravel
coravel copied to clipboard
Dependency injection for job with parameters
Describe the bug I'm trying to setup dependency injection for a new scheduled job with parameters and followed the following documentation section, without much success.
In my Program.cs
class, I do the following for registration:
services.AddTransient<MyJob>();
For the MyJob
class, the single parameter (e.g. MyParams
) is right after other injected dependencies.
On startup, here's the strack trace I get:
Unhandled exception. System.AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: MyNamespace.MyJob Lifetime: Transient ImplementationType: MyNamespace.MyJob': Unable to resolve service for type 'MyNamespace.MyParams' while attempting to activate 'MyNamespace.MyJob'.)
Affected Coravel Feature Scheduling, but it could apply to other features as well
Expected behaviour I'm unsure whether I'm missing a step here or if the registration is incorrect, but I shall be capable of registering jobs with parameters 😄
Note that I'm running on .NET 6, which might have an impact, but I don't know for sure, and Coravel being at the latest version.
Did you call ScheduleWithParams<MyJob>()
in your configuration too?
Did you call
ScheduleWithParams<MyJob>()
in your configuration too?
Regarding this, it may lead to another question I had regarding this library. Is it possible to inject IScheduler
within a class and schedule on-demand jobs? Within a class registered for dependency injection, IScheduler
is injected in it like such:
public class MyService
{
private readonly IScheduler _scheduler;
public MyService(IScheduler scheduler)
{
_scheduler = scheduler;
}
public async Task SomeMethodAsync()
{
// Parameters may be created here or passed to the current method, for instance
MyParams parameters = new();
// some asynchronous logic
_scheduler
.ScheduleWithParams<MyJob>(parameters)
.Every30Minutes();
}
}
For context, I have the following workflow that I would like to do in my app:
- Every 30 minutes, I have a look at my calendar for time-bounded events
- If an event started on time, I shall track the event for inner events every 5 minutes and the previous scheduling shall be unregistered
- Once the aforementioned event ends, then the scheduling would be unregistered
So it's not an officially a public thing (yet?), but it's possible if you really want to - check out this issue for some specifics: https://github.com/jamesmh/coravel/issues/77
Got the same issue here.
I figured it out. When you call ScheduleWithParams<T>
, you don't need to register it as a transient just like the documentation said at this part :
https://docs.coravel.net/Invocables/#manually
Coravel actually resolve all the dependency by itself (wich is really great stuff).
Maybe adding this to the documentation could help some people who got the same issue.
I figured it out. When you call
ScheduleWithParams<T>
, you don't need to register it as a transient just like the documentation said at this part : https://docs.coravel.net/Invocables/#manuallyCoravel actually resolve all the dependency by itself (wich is really great stuff).
Maybe adding this to the documentation could help some people who got the same issue.
@Jofrais, I had the same experience. @jamesmh is this expected behavior contrary to documentation?
This has to do with how this code path creates/instantiates the object/invocable. Is it expected? No lol. I can see why it's the case though. Will have to investigate if there's a way to do this via the service container to keep the experience consistent, or if not then make that an explicit difference called out in the docs.
@jamesmh thanks for the prompt response.
Same issue for me too, solved like @Jofrais
Will close for now. Might revisit but for now it works with the disclaimer to not register to DI.
Added something in the docs around this.