diff --git a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AbpBackgroundJobsAbstractionsModule.cs b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AbpBackgroundJobsAbstractionsModule.cs index 38a0afb2cd..2b5f6fa7a5 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AbpBackgroundJobsAbstractionsModule.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AbpBackgroundJobsAbstractionsModule.cs @@ -23,7 +23,8 @@ namespace Volo.Abp.BackgroundJobs services.OnRegistred(context => { - if (ReflectionHelper.IsAssignableToGenericType(context.ImplementationType, typeof(IBackgroundJob<>))) + if (ReflectionHelper.IsAssignableToGenericType(context.ImplementationType, typeof(IBackgroundJob<>)) || + ReflectionHelper.IsAssignableToGenericType(context.ImplementationType, typeof(IAsyncBackgroundJob<>))) { jobTypes.Add(context.ImplementationType); } diff --git a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AsyncBackgroundJob.cs b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AsyncBackgroundJob.cs new file mode 100644 index 0000000000..3c76bd718e --- /dev/null +++ b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AsyncBackgroundJob.cs @@ -0,0 +1,20 @@ +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; + +namespace Volo.Abp.BackgroundJobs +{ + public abstract class AsyncBackgroundJob : IAsyncBackgroundJob + { + //TODO: Add UOW, Localization and other useful properties..? + + public ILogger> Logger { get; set; } + + protected AsyncBackgroundJob() + { + Logger = NullLogger>.Instance; + } + + public abstract Task ExecuteAsync(TArgs args); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobArgsHelper.cs b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobArgsHelper.cs index 284a2cbb42..58199a9659 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobArgsHelper.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobArgsHelper.cs @@ -13,7 +13,8 @@ namespace Volo.Abp.BackgroundJobs continue; } - if (@interface.GetGenericTypeDefinition() != typeof(IBackgroundJob<>)) + if (@interface.GetGenericTypeDefinition() != typeof(IBackgroundJob<>) && + @interface.GetGenericTypeDefinition() != typeof(IAsyncBackgroundJob<>)) { continue; } @@ -27,7 +28,9 @@ namespace Volo.Abp.BackgroundJobs return genericArgs[0]; } - throw new AbpException($"Could not find type of the job args. Ensure that given type implements the {typeof(IBackgroundJob<>).AssemblyQualifiedName} interface. Given job type: {jobType.AssemblyQualifiedName}"); + throw new AbpException($"Could not find type of the job args. " + + $"Ensure that given type implements the {typeof(IBackgroundJob<>).AssemblyQualifiedName} or {typeof(IAsyncBackgroundJob<>).AssemblyQualifiedName} interface. " + + $"Given job type: {jobType.AssemblyQualifiedName}"); } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs index df0ec36dd6..ec0ac8ee3f 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs @@ -2,7 +2,9 @@ using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using System; +using System.Threading.Tasks; using Volo.Abp.DependencyInjection; +using Volo.Abp.Threading; namespace Volo.Abp.BackgroundJobs { @@ -27,15 +29,24 @@ namespace Volo.Abp.BackgroundJobs throw new AbpException("The job type is not registered to DI: " + context.JobType); } - var jobExecuteMethod = context.JobType.GetMethod(nameof(IBackgroundJob.Execute)); + var jobExecuteMethod = context.JobType.GetMethod(nameof(IBackgroundJob.Execute)) ?? + context.JobType.GetMethod(nameof(IAsyncBackgroundJob.ExecuteAsync)); if (jobExecuteMethod == null) { - throw new AbpException($"Given job type does not implement {typeof(IBackgroundJob<>).Name}. The job type was: " + context.JobType); + throw new AbpException($"Given job type does not implement {typeof(IBackgroundJob<>).Name} or {typeof(IAsyncBackgroundJob<>).Name}. " + + "The job type was: " + context.JobType); } try { - jobExecuteMethod.Invoke(job, new[] { context.JobArgs }); + if (jobExecuteMethod.Name == nameof(IAsyncBackgroundJob.ExecuteAsync)) + { + AsyncHelper.RunSync(() => (Task) jobExecuteMethod.Invoke(job, new[] {context.JobArgs})); + } + else + { + jobExecuteMethod.Invoke(job, new[] { context.JobArgs }); + } } catch (Exception ex) { diff --git a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IAsyncBackgroundJob.cs b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IAsyncBackgroundJob.cs new file mode 100644 index 0000000000..262d95d35b --- /dev/null +++ b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IAsyncBackgroundJob.cs @@ -0,0 +1,16 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.BackgroundJobs +{ + /// + /// Defines interface of a background job. + /// + public interface IAsyncBackgroundJob + { + /// + /// Executes the job with the . + /// + /// Job arguments. + Task ExecuteAsync(TArgs args); + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobExecuter_Tests.cs b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobExecuter_Tests.cs index 566c69c318..81c76f2559 100644 --- a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobExecuter_Tests.cs +++ b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobExecuter_Tests.cs @@ -1,4 +1,4 @@ -using System.Threading.Tasks; +using System.Threading.Tasks; using Shouldly; using Xunit; @@ -35,5 +35,28 @@ namespace Volo.Abp.BackgroundJobs jobObject.ExecutedValues.ShouldContain("42"); } + + [Fact] + public async Task Should_Execute_Async_Tasks() + { + //Arrange + + var jobObject = GetRequiredService(); + jobObject.ExecutedValues.ShouldBeEmpty(); + + //Act + + _backgroundJobExecuter.Execute( + new JobExecutionContext( + ServiceProvider, + typeof(MyAsyncJob), + new MyAsyncJobArgs("42") + ) + ); + + //Assert + + jobObject.ExecutedValues.ShouldContain("42"); + } } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobManager_Tests.cs b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobManager_Tests.cs index 2c00573bc7..3a84e38df1 100644 --- a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobManager_Tests.cs +++ b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobManager_Tests.cs @@ -23,5 +23,13 @@ namespace Volo.Abp.BackgroundJobs jobIdAsString.ShouldNotBe(default); (await _backgroundJobStore.FindAsync(Guid.Parse(jobIdAsString))).ShouldNotBeNull(); } + + [Fact] + public async Task Should_Store_Async_Jobs() + { + var jobIdAsString = await _backgroundJobManager.EnqueueAsync(new MyAsyncJobArgs("42")); + jobIdAsString.ShouldNotBe(default); + (await _backgroundJobStore.FindAsync(Guid.Parse(jobIdAsString))).ShouldNotBeNull(); + } } } diff --git a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyAsyncJob.cs b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyAsyncJob.cs new file mode 100644 index 0000000000..a728d85deb --- /dev/null +++ b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyAsyncJob.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.BackgroundJobs +{ + public class MyAsyncJob : AsyncBackgroundJob, ISingletonDependency + { + public List ExecutedValues { get; } = new List(); + + public override Task ExecuteAsync(MyAsyncJobArgs args) + { + ExecutedValues.Add(args.Value); + + return Task.CompletedTask; + } + } +} diff --git a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyAsyncJobArgs.cs b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyAsyncJobArgs.cs new file mode 100644 index 0000000000..7a12d2a925 --- /dev/null +++ b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyAsyncJobArgs.cs @@ -0,0 +1,17 @@ +namespace Volo.Abp.BackgroundJobs +{ + public class MyAsyncJobArgs + { + public string Value { get; set; } + + public MyAsyncJobArgs() + { + + } + + public MyAsyncJobArgs(string value) + { + Value = value; + } + } +} \ No newline at end of file