diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index 12f37c0..3980a5c 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -8,7 +8,7 @@
Tingle Software
Tingle Software
$(PackageTags);periodic;tasks;cron;cronjob;scheduled
- true
+ true
diff --git a/src/Tingle.PeriodicTasks.AspNetCore/PeriodicTasksEndpointRouteBuilderExtensions.cs b/src/Tingle.PeriodicTasks.AspNetCore/PeriodicTasksEndpointRouteBuilderExtensions.cs
index 57400fe..c1d9d26 100644
--- a/src/Tingle.PeriodicTasks.AspNetCore/PeriodicTasksEndpointRouteBuilderExtensions.cs
+++ b/src/Tingle.PeriodicTasks.AspNetCore/PeriodicTasksEndpointRouteBuilderExtensions.cs
@@ -13,14 +13,16 @@ namespace Microsoft.AspNetCore.Builder;
///
public static class PeriodicTasksEndpointRouteBuilderExtensions
{
- internal const string MapEndpointTrimmerWarning = "This API may perform reflection on the supplied delegate and its parameters. These types may be trimmed if not directly referenced.";
+ private const string MapEndpointUnreferencedCodeWarning = "This API may perform reflection on the supplied delegate and its parameters. These types may be trimmed if not directly referenced.";
+ private const string MapEndpointDynamicCodeWarning = "This API may perform reflection on the supplied delegate and its parameters. These types may require generated code and aren't compatible with native AOT applications.";
///
/// Maps incoming requests to the paths for periodic tasks.
///
/// The to add the routes to.
/// A for endpoints associated with periodic tasks.
- [RequiresUnreferencedCode(MapEndpointTrimmerWarning)]
+ [RequiresUnreferencedCode(MapEndpointUnreferencedCodeWarning)]
+ [RequiresDynamicCode(MapEndpointDynamicCodeWarning)]
public static IEndpointConventionBuilder MapPeriodicTasks(this IEndpointRouteBuilder endpoints)
{
ArgumentNullException.ThrowIfNull(endpoints);
diff --git a/src/Tingle.PeriodicTasks.AspNetCore/PeriodicTasksEndpointsHandler.cs b/src/Tingle.PeriodicTasks.AspNetCore/PeriodicTasksEndpointsHandler.cs
index c3611f7..abaf2a0 100644
--- a/src/Tingle.PeriodicTasks.AspNetCore/PeriodicTasksEndpointsHandler.cs
+++ b/src/Tingle.PeriodicTasks.AspNetCore/PeriodicTasksEndpointsHandler.cs
@@ -12,7 +12,7 @@ public List GetRegistrations()
{
var registrations = hostOptions.Registrations;
var results = new List();
- foreach (var (name, type) in registrations)
+ foreach (var (name, (type, _)) in registrations)
{
var options = optionsMonitor.Get(name);
results.Add(new()
diff --git a/src/Tingle.PeriodicTasks/DependencyInjection/PeriodicTaskConfigureOptions.cs b/src/Tingle.PeriodicTasks/DependencyInjection/PeriodicTaskConfigureOptions.cs
index 877a691..ea63b82 100644
--- a/src/Tingle.PeriodicTasks/DependencyInjection/PeriodicTaskConfigureOptions.cs
+++ b/src/Tingle.PeriodicTasks/DependencyInjection/PeriodicTaskConfigureOptions.cs
@@ -24,7 +24,7 @@ public void Configure(string? name, PeriodicTaskOptions options)
ArgumentException.ThrowIfNullOrEmpty(name);
// set schedule and timezone from Attribute
- var type = tasksHostOptions.Registrations[name];
+ var (type, _) = tasksHostOptions.Registrations[name];
var attrs = type.GetCustomAttributes(false);
if (attrs.OfType().SingleOrDefault() is PeriodicTaskScheduleAttribute attrSchedule)
{
diff --git a/src/Tingle.PeriodicTasks/DependencyInjection/PeriodicTasksBuilder.cs b/src/Tingle.PeriodicTasks/DependencyInjection/PeriodicTasksBuilder.cs
index 5ae5215..c7dda25 100644
--- a/src/Tingle.PeriodicTasks/DependencyInjection/PeriodicTasksBuilder.cs
+++ b/src/Tingle.PeriodicTasks/DependencyInjection/PeriodicTasksBuilder.cs
@@ -85,8 +85,6 @@ public PeriodicTasksBuilder Configure(Action configure
{
ArgumentNullException.ThrowIfNull(configure);
- var tt = typeof(TTask);
-
Configure(opt =>
{
if (opt.Registrations.TryGetValue(name, out var r))
@@ -94,7 +92,7 @@ public PeriodicTasksBuilder Configure(Action configure
throw new InvalidOperationException($"A task with the name '{name}' has already been registered. Names are case insensitive.");
}
- opt.AddRegistration(name, tt);
+ opt.AddRegistration(name);
});
Services.Configure(name, configure);
diff --git a/src/Tingle.PeriodicTasks/DependencyInjection/PeriodicTasksHostOptions.cs b/src/Tingle.PeriodicTasks/DependencyInjection/PeriodicTasksHostOptions.cs
index 817a199..0321e81 100644
--- a/src/Tingle.PeriodicTasks/DependencyInjection/PeriodicTasksHostOptions.cs
+++ b/src/Tingle.PeriodicTasks/DependencyInjection/PeriodicTasksHostOptions.cs
@@ -13,7 +13,7 @@ public class PeriodicTasksHostOptions
/// Names must be case-insensitive because they are used to form lock names and the underlying distributed
/// lock provider may not support case sensitivity.
/// For example, using files for locks may fail because file names on Windows are case insensitive.
- private readonly Dictionary registrations = new(StringComparer.OrdinalIgnoreCase);
+ private readonly Dictionary registrations = new(StringComparer.OrdinalIgnoreCase);
///
/// Gets or sets the prefix value for the lock names.
@@ -64,7 +64,21 @@ public class PeriodicTasksHostOptions
public PeriodicTaskIdFormat DefaultExecutionIdFormat { get; set; } = PeriodicTaskIdFormat.GuidNoDashes;
/// The periodic tasks registered.
- public IReadOnlyDictionary Registrations => registrations;
+ public IReadOnlyDictionary Registrations => registrations;
- internal void AddRegistration(string name, [DynamicallyAccessedMembers(TrimmingHelper.Task)] Type type) => registrations.Add(name, type);
+ internal void AddRegistration<[DynamicallyAccessedMembers(TrimmingHelper.Task)] TTask>(string name)
+ => registrations.Add(name, new(typeof(TTask), typeof(IPeriodicTaskRunner)));
+}
+
+/// Registration for a periodic task.
+public readonly record struct PeriodicTaskTypeRegistration([DynamicallyAccessedMembers(TrimmingHelper.Task)] Type Type, [DynamicallyAccessedMembers(TrimmingHelper.Task)] Type RunnerType)
+{
+ /// Deconstructs the registration into its parts.
+ /// The type of the periodic task.
+ /// The type of the runner for the periodic task.
+ public void Deconstruct(out Type type, out Type runnerType)
+ {
+ type = Type;
+ runnerType = RunnerType;
+ }
}
diff --git a/src/Tingle.PeriodicTasks/Internal/PeriodicTaskRunnerCreator.cs b/src/Tingle.PeriodicTasks/Internal/PeriodicTaskRunnerCreator.cs
index 0680c3e..1cb43c2 100644
--- a/src/Tingle.PeriodicTasks/Internal/PeriodicTaskRunnerCreator.cs
+++ b/src/Tingle.PeriodicTasks/Internal/PeriodicTaskRunnerCreator.cs
@@ -1,6 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
-using System.Diagnostics.CodeAnalysis;
namespace Tingle.PeriodicTasks.Internal;
@@ -11,19 +10,14 @@ internal class PeriodicTaskRunnerCreator(IServiceProvider provider, IOptions builder.AddTask(...)) when configuring your host.");
}
- return Create(type);
+ return Create(registration);
}
- public IPeriodicTaskRunner Create([DynamicallyAccessedMembers(TrimmingHelper.Task)] Type type)
- {
- var genericRunnerType = typeof(IPeriodicTaskRunner<>);
- var runnerType = genericRunnerType.MakeGenericType(type);
- return (IPeriodicTaskRunner)provider.GetRequiredService(runnerType);
- }
+ public IPeriodicTaskRunner Create(PeriodicTaskTypeRegistration registration) => (IPeriodicTaskRunner)provider.GetRequiredService(registration.RunnerType);
}
diff --git a/src/Tingle.PeriodicTasks/Internal/PeriodicTasksHost.cs b/src/Tingle.PeriodicTasks/Internal/PeriodicTasksHost.cs
index 5cf8b19..26a880a 100644
--- a/src/Tingle.PeriodicTasks/Internal/PeriodicTasksHost.cs
+++ b/src/Tingle.PeriodicTasks/Internal/PeriodicTasksHost.cs
@@ -23,10 +23,9 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
// create the tasks
var tasks = new List();
- foreach (var registration in options.Registrations)
+ foreach (var (name, registration) in options.Registrations)
{
- var (name, type) = registration;
- var runner = creator.Create(type);
+ var runner = creator.Create(registration);
tasks.Add(runner.RunAsync(name, stoppingToken));
}