mirror of
https://github.com/kevincolyar/CronNET.git
synced 2024-05-17 13:12:36 +02:00
Adding a layer for dependency injection and hosted services
This commit is contained in:
parent
f1275079a6
commit
e3d387b2cd
|
@ -0,0 +1,72 @@
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace crondotnet.Extensions.DependencyInjection
|
||||
{
|
||||
public class CronDaemonHostedService : IHostedService
|
||||
{
|
||||
public CronDaemonHostedService(
|
||||
IServiceProvider serviceProvider)
|
||||
{
|
||||
ServiceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
private AsyncServiceScope Scope { get; set; }
|
||||
|
||||
private IServiceProvider ServiceProvider { get; }
|
||||
|
||||
private ICronDaemon CronDaemon { get; set; }
|
||||
|
||||
public async Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
Scope = ServiceProvider.CreateAsyncScope();
|
||||
|
||||
CronDaemon = Scope.ServiceProvider.GetRequiredService<ICronDaemon>();
|
||||
var options = Scope.ServiceProvider.GetRequiredService<IOptions<CronDaemonOptions>>();
|
||||
|
||||
foreach (var job in options.Value.Jobs)
|
||||
{
|
||||
if (job.StaticTask != null)
|
||||
{
|
||||
CronDaemon.AddJob(job.Expression, job.StaticTask);
|
||||
}
|
||||
else if (job.ServiceType != null)
|
||||
{
|
||||
var service = Scope.ServiceProvider.GetRequiredService(job.ServiceType) as IThinService;
|
||||
if (service != null)
|
||||
{
|
||||
CronDaemon.AddJob(job.Expression, new ThinServiceCronWrapper(service).RunService);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// nothing set up for the run task.
|
||||
}
|
||||
}
|
||||
|
||||
await CronDaemon.StartAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public async Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await CronDaemon.StopAsync();
|
||||
await Scope.DisposeAsync();
|
||||
}
|
||||
|
||||
private class ThinServiceCronWrapper
|
||||
{
|
||||
public ThinServiceCronWrapper(IThinService service)
|
||||
{
|
||||
Service = service;
|
||||
}
|
||||
|
||||
private IThinService Service { get; }
|
||||
|
||||
public async Task RunService(CancellationToken cancellationToken)
|
||||
{
|
||||
await Service.Run(cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
internal class CronDaemonOptions
|
||||
{
|
||||
public List<JobOptions> Jobs { get; set; } = new List<JobOptions>();
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
using crondotnet;
|
||||
using crondotnet.Extensions.DependencyInjection;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
public static class CronServiceProverExtensions
|
||||
{
|
||||
public static IServiceCollection AddCron(this IServiceCollection services, Action<ICronDaemonOptionsBuilder>? optionsAction = null)
|
||||
{
|
||||
services.AddSingleton<CronDaemonHostedService>();
|
||||
services.AddScoped<ICronDaemon, CronDaemon>();
|
||||
|
||||
var cronDaemonOptionsBuilder = new CronDaemonOptionsBuilder();
|
||||
optionsAction?.Invoke(cronDaemonOptionsBuilder);
|
||||
services.ConfigureOptions(cronDaemonOptionsBuilder.Build());
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
||||
public interface ICronDaemonOptionsBuilder
|
||||
{
|
||||
ICronDaemonOptionsBuilder AddJob(string cronExpression, ExecuteCronJob job);
|
||||
|
||||
ICronDaemonOptionsBuilder AddJob<TService>(string cronExpression) where TService : IThinService;
|
||||
}
|
||||
|
||||
public class CronDaemonOptionsBuilder : ICronDaemonOptionsBuilder
|
||||
{
|
||||
private readonly CronDaemonOptions Options = new CronDaemonOptions();
|
||||
|
||||
public ICronDaemonOptionsBuilder AddJob(string cronExpression, ExecuteCronJob job)
|
||||
{
|
||||
Options.Jobs.Add(new JobOptions
|
||||
{
|
||||
Expression = cronExpression,
|
||||
StaticTask = job
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ICronDaemonOptionsBuilder AddJob<TService>(string cronExpression)
|
||||
where TService : IThinService
|
||||
{
|
||||
Options.Jobs.Add(new JobOptions
|
||||
{
|
||||
Expression = cronExpression,
|
||||
ServiceType = typeof(TService),
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
internal CronDaemonOptions Build()
|
||||
{
|
||||
return Options;
|
||||
}
|
||||
}
|
||||
}
|
13
crondotnet.Extensions.DependencyInjection/IThinService.cs
Normal file
13
crondotnet.Extensions.DependencyInjection/IThinService.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace crondotnet
|
||||
{
|
||||
public interface IThinService
|
||||
{
|
||||
Task Run(CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
11
crondotnet.Extensions.DependencyInjection/JobOptions.cs
Normal file
11
crondotnet.Extensions.DependencyInjection/JobOptions.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
using crondotnet;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
public class JobOptions
|
||||
{
|
||||
public string Expression { get; set; }
|
||||
public ExecuteCronJob StaticTask { get; set; }
|
||||
public Type ServiceType { get; internal set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6;net7</TargetFrameworks>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>crondotnet</RootNamespace>
|
||||
<AssemblyName>crondotnet.Extensions.Hosting</AssemblyName>
|
||||
<Authors>kevinkolyar, iminet, tycoff</Authors>
|
||||
<Product>C# library for running cron jobs on .NET</Product>
|
||||
<PackageId>crondotnet.Extensions.Hosting</PackageId>
|
||||
<PackageProjectUrl>https://github.com/tycoff/crondotnet</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/tycoff/crondotnet</RepositoryUrl>
|
||||
<PackageTags>dotnet Cron Crondaemon Crontab</PackageTags>
|
||||
<Version>0.1.1.0</Version>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\crondotnet\crondotnet.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -7,10 +7,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "crondotnet", "crondotnet\cr
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "crondotnet.Tests", "crondotnet.Tests\crondotnet.Tests.csproj", "{6FCFBDF4-ECB7-4FC2-A376-E962B11D487D}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{6753321E-D4F3-4199-872D-8986A596453E}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
Readme.md = Readme.md
|
||||
EndProjectSection
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "crondotnet.Extensions.Hosting", "crondotnet.Extensions.DependencyInjection\crondotnet.Extensions.Hosting.csproj", "{5A6713CE-4366-497C-AA82-C2CEB3276CFA}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -26,6 +23,10 @@ Global
|
|||
{6FCFBDF4-ECB7-4FC2-A376-E962B11D487D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6FCFBDF4-ECB7-4FC2-A376-E962B11D487D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6FCFBDF4-ECB7-4FC2-A376-E962B11D487D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5A6713CE-4366-497C-AA82-C2CEB3276CFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5A6713CE-4366-497C-AA82-C2CEB3276CFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5A6713CE-4366-497C-AA82-C2CEB3276CFA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5A6713CE-4366-497C-AA82-C2CEB3276CFA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -52,13 +52,20 @@ namespace crondotnet
|
|||
{
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
await timer.WaitForNextTickAsync(cancellationToken);
|
||||
|
||||
if (!cancellationToken.IsCancellationRequested && DateTime.Now.Minute != _last.Minute)
|
||||
try
|
||||
{
|
||||
_last = DateTime.Now;
|
||||
foreach (ICronJob job in cronJobs)
|
||||
job.Execute(DateTime.Now, cancellationToken);
|
||||
await timer.WaitForNextTickAsync(cancellationToken);
|
||||
|
||||
if (!cancellationToken.IsCancellationRequested && DateTime.Now.Minute != _last.Minute)
|
||||
{
|
||||
_last = DateTime.Now;
|
||||
foreach (ICronJob job in cronJobs)
|
||||
job.Execute(DateTime.Now, cancellationToken);
|
||||
}
|
||||
}
|
||||
catch (TaskCanceledException)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,11 +10,7 @@
|
|||
<PackageProjectUrl>https://github.com/tycoff/crondotnet</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/tycoff/crondotnet</RepositoryUrl>
|
||||
<PackageTags>dotnet Cron Crondaemon Crontab</PackageTags>
|
||||
<Version>0.1.0.0</Version>
|
||||
<Version>0.1.2.0</Version>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\Readme.md" Pack="true" PackagePath="\"/>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Reference in New Issue
Block a user