The use of service locator is concerning me! 😊 Why don't you just switch to DI?
public class AgrodeskSendLogisticProductsJob : ScheduledJobBase
{
private readonly ILogisticProductsService _logisticProductsService;
private readonly IUserImpersonation _userImpersonation;
public AgrodeskSendLogisticProductsJob(ILogisticProductsService logisticProductsService, IUserImpersonation userImpersonation)
{
_logisticProductsService = logisticProductsService;
_userImpersonation = userImpersonation;
}
public override string Execute()
{
PrincipalInfo.CurrentPrincipal = _userImpersonation.CreatePrincipal("saam.farmer@lm2.com");
_logisticProductsService.SendProducts();
return "OK";
}
}
I'm thinking that your issue is potentially stemming from that fact that you have 2 constructors, I'm wondering if different one's are hit when it's a manual vs scheduled run. Although that stil doesn't really change things if you're registering the service correctly in the service container--which it looks like you are.
Hello Jake,
Thank you for response.
Actually I did have only one constructor earlier with DI. but It started giveing error to have a default constructor in scheduledjob.
error was "The scheduled job of type 'Gro.ScheduledJob.AgrodeskSendLogisticProductsJob' cannot be created. It must either be registered in the IOC container or have a default constructor."
Thats the reason I created one default constructor with having servilocator.
What version of the CMS are you using? If it's > 10.3 then jobs support DI: https://blog.tech-fellow.net/2016/12/28/scheduled-jobs-updates/
What happens if you remove your additional constructor then (and align your handling of dependencies):
public class AgrodeskSendLogisticProductsJob : ScheduledJobBase
{
private readonly ILogisticProductsService _logisticProductsService;
private readonly IUserImpersonation _userImpersonation;
public AgrodeskSendLogisticProductsJob()
{
_logisticProductsService = ServiceLocator.Current.GetInstance<ILogisticProductsService>();
_userImpersonation = ServiceLocator.Current.GetInstance<IUserImpersonation>();
}
}
If you're still getting an exception I'd be interested to know whether the IUserImpersonation is resolving.
My CMS version 11.20.
I have already tried removing additional constructor and gettting instance through ServiceLocator. But the result is same.
I was under impression that it is not working because I am not impersonating an user with admin credentials. that the reason I added impersonation to impersonate and admin user account. But no luck with it.
Hi again,
Sorry if I wasn't clear--but I think Ted is on to something. I think you need to try narrowing down the problem and ruling things out.
ILogisticProductsService
elsewhere? If not, then how does the constructor look for it?IContentLoader
, does that work? (i.e. remove all uses of ILogisticProductsService
)Based on your last response I think you should also remove usages of IUserImpersonation
.
public LogisticProductsService(FormDataRepository formDataRepository, IFormRepository formRepository, IEmailService client, IContentRepository contentRepository,
SiteDefinitionRepository siteDefinitionRepository)
{
_formDataRepository = formDataRepository;
_formRepository = formRepository;
_client = client;
_contentRepository = contentRepository;
_siteDefinitionRepository = siteDefinitionRepository;
}
This how my service constructor is defined for logistic service.
I tried with a default constructor. and creating instances for all those injected services using Servicelocator. But then it faild to create instance of IEmailService with same error.
It looks like it is failing to create instance only for customer services.
Ok, well now we're getting somewhere.
Is IEmailService
registered correctly? Or does it have a dependency that is not registered correctly? I'm pretty sure that's got to be your problem.
Could you get the full log? It seems that one of the dependency could not be resolved down the line. and given that you can run it manually, it might have something with the account
You mentioned that the job works if you trigger it manually. One big difference when running a job manually vs automatically is the presence of the HttpContext. Does IEmailService depend on the HttpContext?
If so, you need to refactor the IEmailService into something that can run without the HttpContext.
I also experienced the error "The scheduled job of type 'XZXZ' cannot be created. It must either be registered in the IOC container or have a default constructor.". In my case it was one of the injected dependencies that threw an exception in its constructor when it was trying to access Azure Keyvault. The failure was due to AK no longer accepting clients using TLS 1.0. A server configuration issue, in other words.
Hi,
I am facing an issue with scheduled job, that its not able to start automatically. I am getting below error:
I have a sercvice injected into scheduled job constructor. The job works fine if I manually trigger the job.
code snipest:
The dependancies are resolved in dependancy resolver.
anyone could you help whats wrong with this approach?