diff --git a/src/Web/Grand.Web.Admin/Controllers/ScheduleTaskController.cs b/src/Web/Grand.Web.Admin/Controllers/ScheduleTaskController.cs
index 53e38fcbd..a9164e9e4 100644
--- a/src/Web/Grand.Web.Admin/Controllers/ScheduleTaskController.cs
+++ b/src/Web/Grand.Web.Admin/Controllers/ScheduleTaskController.cs
@@ -117,8 +117,7 @@ public async Task EditScheduler(ScheduleTaskModel model, bool con
return RedirectToAction("List");
}
- model.ScheduleTaskName = scheduleTask.ScheduleTaskName;
- model.Type = scheduleTask.Type;
+ model.ScheduleTaskName = scheduleTask.ScheduleTaskName;
model = await PrepareStores(model);
Error(ModelState);
@@ -132,9 +131,8 @@ public async Task RunNow(string id)
{
var scheduleTask = await _scheduleTaskService.GetTaskById(id);
if (scheduleTask == null) throw new Exception("Schedule task cannot be loaded");
- var typeofTask = Type.GetType(scheduleTask.Type);
- var task = HttpContext.RequestServices.GetServices()
- .FirstOrDefault(x => x.GetType() == typeofTask);
+
+ var task = HttpContext.RequestServices.GetRequiredKeyedService(scheduleTask.ScheduleTaskName);
if (task != null)
{
scheduleTask.LastStartUtc = DateTime.UtcNow;
@@ -157,7 +155,7 @@ public async Task RunNow(string id)
}
else
{
- Error($"Task {typeofTask?.Name} has not been registered");
+ Error($"Task {scheduleTask.ScheduleTaskName} has not been registered");
}
}
catch (Exception exc)
diff --git a/src/Web/Grand.Web.Admin/Mapper/ScheduleTaskProfile.cs b/src/Web/Grand.Web.Admin/Mapper/ScheduleTaskProfile.cs
index ffdce8708..cc296e8b4 100644
--- a/src/Web/Grand.Web.Admin/Mapper/ScheduleTaskProfile.cs
+++ b/src/Web/Grand.Web.Admin/Mapper/ScheduleTaskProfile.cs
@@ -14,7 +14,6 @@ public ScheduleTaskProfile()
CreateMap()
.ForMember(dest => dest.Id, mo => mo.Ignore())
- .ForMember(dest => dest.Type, mo => mo.Ignore())
.ForMember(dest => dest.ScheduleTaskName, mo => mo.Ignore())
.ForMember(dest => dest.LastNonSuccessEndUtc, mo => mo.Ignore())
.ForMember(dest => dest.LastStartUtc, mo => mo.Ignore())
diff --git a/src/Web/Grand.Web.Admin/Models/Tasks/ScheduleTaskModel.cs b/src/Web/Grand.Web.Admin/Models/Tasks/ScheduleTaskModel.cs
index db153ca1f..b4c44c4e4 100644
--- a/src/Web/Grand.Web.Admin/Models/Tasks/ScheduleTaskModel.cs
+++ b/src/Web/Grand.Web.Admin/Models/Tasks/ScheduleTaskModel.cs
@@ -10,10 +10,7 @@ public class ScheduleTaskModel : BaseEntityModel
public string ScheduleTaskName { get; set; }
[GrandResourceDisplayName("Admin.System.ScheduleTasks.LeasedByMachineName")]
- public string LeasedByMachineName { get; set; }
-
- [GrandResourceDisplayName("Admin.System.ScheduleTasks.Type")]
- public string Type { get; set; }
+ public string LeasedByMachineName { get; set; }
[GrandResourceDisplayName("Admin.System.ScheduleTasks.Enabled")]
public bool Enabled { get; set; }
diff --git a/src/Web/Grand.Web.Common/Extensions/KeyedServiceHelper.cs b/src/Web/Grand.Web.Common/Extensions/KeyedServiceHelper.cs
new file mode 100644
index 000000000..678e9bc2d
--- /dev/null
+++ b/src/Web/Grand.Web.Common/Extensions/KeyedServiceHelper.cs
@@ -0,0 +1,19 @@
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Grand.Web.Common.Extensions;
+
+public static class KeyedServiceHelper
+{
+ public static IList GetKeyedServicesForInterface(IServiceCollection services)
+ {
+ var keyedServices = new List();
+ foreach (var service in services)
+ {
+ if (service.ServiceType == typeof(TInterface) && service.IsKeyedService)
+ {
+ keyedServices.Add(service.ServiceKey.ToString());
+ }
+ }
+ return keyedServices;
+ }
+}
\ No newline at end of file
diff --git a/src/Web/Grand.Web.Common/Infrastructure/BackgroundServiceTask.cs b/src/Web/Grand.Web.Common/Infrastructure/BackgroundServiceTask.cs
index 7c87adc98..01517ebca 100644
--- a/src/Web/Grand.Web.Common/Infrastructure/BackgroundServiceTask.cs
+++ b/src/Web/Grand.Web.Common/Infrastructure/BackgroundServiceTask.cs
@@ -10,11 +10,11 @@ namespace Grand.Web.Common.Infrastructure;
public class BackgroundServiceTask : BackgroundService
{
private readonly IServiceProvider _serviceProvider;
- private readonly string _taskType;
+ private readonly string Name;
- public BackgroundServiceTask(string taskType, IServiceProvider serviceProvider)
+ public BackgroundServiceTask(string name, IServiceProvider serviceProvider)
{
- _taskType = taskType;
+ Name = name;
_serviceProvider = serviceProvider;
}
@@ -27,10 +27,10 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
var serviceProvider = scope.ServiceProvider;
var logger = serviceProvider.GetService>();
var scheduleTaskService = serviceProvider.GetService();
- var task = await scheduleTaskService.GetTaskByType(_taskType);
+ var task = await scheduleTaskService.GetTaskByName(Name);
if (task == null)
{
- logger.LogInformation("Task {TaskType} is not exists in the database", _taskType);
+ logger.LogInformation("Task {TaskName} is not exists in the database", Name);
break;
}
@@ -39,66 +39,55 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
if (task.Enabled && (string.IsNullOrEmpty(task.LeasedByMachineName) ||
machineName == task.LeasedByMachineName))
{
- var typeofTask = Type.GetType(_taskType);
- if (typeofTask != null)
+
+ var scheduleTask = serviceProvider.GetRequiredKeyedService(task.ScheduleTaskName);
+ if (scheduleTask != null)
{
- var scheduleTask = serviceProvider.GetServices()
- .FirstOrDefault(x => x.GetType() == typeofTask);
- if (scheduleTask != null)
+ //assign current customer (background task) / current store (from task)
+ await WorkContext(serviceProvider, task);
+ var runTask = true;
+ if (task.LastStartUtc.HasValue)
{
- //assign current customer (background task) / current store (from task)
- await WorkContext(serviceProvider, task);
- var runTask = true;
- if (task.LastStartUtc.HasValue)
+ var dateTimeNow = DateTime.UtcNow;
+ if (dateTimeNow < task.LastStartUtc.Value.AddMinutes(task.TimeInterval))
{
- var dateTimeNow = DateTime.UtcNow;
- if (dateTimeNow < task.LastStartUtc.Value.AddMinutes(task.TimeInterval))
- {
- runTask = false;
- timeInterval =
- (int)(task.LastStartUtc.Value.AddMinutes(task.TimeInterval) - dateTimeNow)
- .TotalMinutes;
- }
- else
- {
- runTask = true;
- timeInterval = task.TimeInterval > 0 ? task.TimeInterval : 1;
- }
+ runTask = false;
+ timeInterval =
+ (int)(task.LastStartUtc.Value.AddMinutes(task.TimeInterval) - dateTimeNow)
+ .TotalMinutes;
}
-
- if (runTask)
+ else
{
- task.LastStartUtc = DateTime.UtcNow;
- try
- {
- //TODO - add settings
- //logger.Information($"Task {_taskType} execute");
- await scheduleTask.Execute();
- task.LastSuccessUtc = DateTime.UtcNow;
- task.LastNonSuccessEndUtc = null;
- }
- catch (Exception exc)
- {
- task.LastNonSuccessEndUtc = DateTime.UtcNow;
- task.Enabled = !task.StopOnError;
- logger.LogError(exc,
- "Error while running the \'{TaskScheduleTaskName}\' schedule task",
- task.ScheduleTaskName);
- }
+ runTask = true;
+ timeInterval = task.TimeInterval > 0 ? task.TimeInterval : 1;
}
}
- else
+
+ if (runTask)
{
- task.Enabled = !task.StopOnError;
- task.LastNonSuccessEndUtc = DateTime.UtcNow;
- logger.LogError("Type {TaskType} is not registered", _taskType);
+ task.LastStartUtc = DateTime.UtcNow;
+ try
+ {
+ logger.LogInformation($"Task {Name} execute");
+ await scheduleTask.Execute();
+ task.LastSuccessUtc = DateTime.UtcNow;
+ task.LastNonSuccessEndUtc = null;
+ }
+ catch (Exception exc)
+ {
+ task.LastNonSuccessEndUtc = DateTime.UtcNow;
+ task.Enabled = !task.StopOnError;
+ logger.LogError(exc,
+ "Error while running the \'{TaskScheduleTaskName}\' schedule task",
+ task.ScheduleTaskName);
+ }
}
}
else
{
task.Enabled = !task.StopOnError;
task.LastNonSuccessEndUtc = DateTime.UtcNow;
- logger.LogError("Type {TaskType} is null (type not exists)", _taskType);
+ logger.LogError("Type {TaskName} is not registered", Name);
}
await scheduleTaskService.UpdateTask(task);
diff --git a/src/Web/Grand.Web.Common/Startup/TaskHandler.cs b/src/Web/Grand.Web.Common/Startup/TaskHandler.cs
index a15da9229..234539e35 100644
--- a/src/Web/Grand.Web.Common/Startup/TaskHandler.cs
+++ b/src/Web/Grand.Web.Common/Startup/TaskHandler.cs
@@ -1,8 +1,6 @@
using Grand.Business.Core.Interfaces.System.ScheduleTasks;
using Grand.Data;
-using Grand.Infrastructure.Configuration;
-using Grand.Infrastructure.Plugins;
-using Grand.Infrastructure.TypeSearch;
+using Grand.Web.Common.Extensions;
using Grand.Web.Common.Infrastructure;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
@@ -17,20 +15,11 @@ public static void RegisterTasks(this IServiceCollection services, IConfiguratio
//database is already installed, so start scheduled tasks
if (!DataSettingsManager.DatabaseIsInstalled()) return;
- var appConfig = new AppConfig();
- configuration.GetSection("Application").Bind(appConfig);
+ var scheduleTaskKeyedServices = KeyedServiceHelper.GetKeyedServicesForInterface(services);
- var typeSearcher = new TypeSearcher();
- var scheduleTasks = typeSearcher.ClassesOfType();
-
- var scheduleTasksInstalled = scheduleTasks
- .Where(PluginExtensions.OnlyInstalledPlugins); //ignore not installed plugins
-
- foreach (var task in scheduleTasksInstalled)
+ foreach (var task in scheduleTaskKeyedServices)
{
- var assemblyName = task.Assembly.GetName().Name;
- services.AddSingleton(sp =>
- new BackgroundServiceTask($"{task.FullName}, {assemblyName}", sp));
+ services.AddSingleton(sp => new BackgroundServiceTask(task, sp));
}
}
}
\ No newline at end of file