NejCommon.NET/AutoScan.cs
2025-01-24 18:15:46 +01:00

86 lines
3.5 KiB
C#

using Microsoft.EntityFrameworkCore;
using Quartz;
namespace NejCommon;
public interface IScopedService
{
}
public interface ISingletonService
{
}
public interface ITransientService
{
}
public interface IBackgroundService
{
}
public interface IRecurringService : IJob
{
public static virtual JobKey? JobKey { get; }
public static abstract string Cron { get; }
}
public interface ISettings
{
string Path { get; }
}
public static class AutoScan
{
public static void RegisterJobs(this IServiceCollection collection, IServiceCollectionQuartzConfigurator conf)
{
var jobs = typeof(IRecurringService).Assembly.GetTypes().Where(x => x.IsAssignableTo(typeof(IRecurringService)) && x != typeof(IRecurringService)).ToList();
foreach (var job in jobs)
{
Console.WriteLine("Testing job: " + job.Name);
var jobKey = job.GetProperty("JobKey")?.GetValue(null) as JobKey ?? new JobKey(job.FullName);
var cron = job.GetProperty("Cron")!.GetValue(null) as string;
if (string.IsNullOrEmpty(cron) || jobKey == null)
{
throw new Exception("Could not register job: " + job.Name);
}
Console.WriteLine("Adding job: " + jobKey.Name + " with cron: " + cron);
conf.AddJob(job, jobKey).AddTrigger(x => x.ForJob(jobKey).WithCronSchedule(cron).StartNow());
}
}
public static void RegisterServices(this IServiceCollection collection)
{
collection.Scan(scan => scan
// We start out with all types in the assembly of ITransientService
.FromAssemblyOf<ITransientService>()
// AddClasses starts out with all public, non-abstract types in this assembly.
// These types are then filtered by the delegate passed to the method.
// In this case, we filter out only the classes that are assignable to ITransientService.
.AddClasses(classes => classes.AssignableTo<ITransientService>())
// We then specify what type we want to register these classes as.
// In this case, we want to register the types as all of its implemented interfaces.
// So if a type implements 3 interfaces; A, B, C, we'd end up with three separate registrations.
.AsSelf()
// And lastly, we specify the lifetime of these registrations.
.WithTransientLifetime()
// Here we start again, with a new full set of classes from the assembly above.
// This time, filtering out only the classes assignable to IScopedService.
.AddClasses(classes => classes.AssignableTo<IScopedService>())
// Now, we just want to register these types as a single interface, IScopedService.
.AsSelf()
// And again, just specify the lifetime.
.WithScopedLifetime()
.AddClasses(classes => classes.AssignableTo<ISingletonService>())
.AsSelf()
.AsImplementedInterfaces()
.WithSingletonLifetime()
.AddClasses(classes => classes.AssignableTo<IBackgroundService>())
.AsSelf()
.AsImplementedInterfaces()
.WithSingletonLifetime()
);
}
}