diff --git a/src/NCronJob/Registry/JobRegistry.cs b/src/NCronJob/Registry/JobRegistry.cs index 0559118..a693729 100644 --- a/src/NCronJob/Registry/JobRegistry.cs +++ b/src/NCronJob/Registry/JobRegistry.cs @@ -4,9 +4,11 @@ namespace NCronJob; internal sealed class JobRegistry { - private readonly HashSet<JobDefinition> allJobs = new(JobDefinitionEqualityComparer.Instance); + private readonly HashSet<JobDefinition> allJobs + = new(JobDefinitionEqualityComparer.Pure); public List<DynamicJobRegistration> DynamicJobRegistrations { get; } = []; - private readonly Dictionary<JobDefinition, List<DependentJobRegistryEntry>> dependentJobsPerJobDefinition = []; + private readonly Dictionary<JobDefinition, List<DependentJobRegistryEntry>> dependentJobsPerJobDefinition + = new(DependentJobDefinitionEqualityComparer.Instance); public IReadOnlyCollection<JobDefinition> GetAllJobs() => [.. allJobs]; @@ -148,4 +150,59 @@ private void AssertNoDuplicateJobNames(string? additionalJobName = null) throw new InvalidOperationException($"Duplicate job names found: {string.Join(", ", duplicateJobName)}"); } } + + private sealed class JobDefinitionEqualityComparer : IEqualityComparer<JobDefinition> + { + public static readonly JobDefinitionEqualityComparer Pure = new(); + + public bool Equals(JobDefinition? x, JobDefinition? y) => + (x is null && y is null) || (x is not null && y is not null + && x.Type == y.Type && x.Type != typeof(DynamicJobFactory) + && x.Parameter == y.Parameter + && x.CronExpression == y.CronExpression + && x.TimeZone == y.TimeZone + && x.CustomName == y.CustomName + && x.IsStartupJob == y.IsStartupJob); + + public int GetHashCode(JobDefinition obj) => HashCode.Combine( + obj.Type, + obj.Parameter, + obj.CronExpression, + obj.TimeZone, + obj.CustomName, + obj.IsStartupJob); + } + + private sealed class DependentJobDefinitionEqualityComparer : IEqualityComparer<JobDefinition> + { + // TODO: Maybe is the code conflating two different concepts. + // Dependent jobs may have a name, a type and a parameter, but that's the most of it. + // And the code currently uses the same type to hold the configuration of "lead" jobs + // and dependent jobs. + // + // Which brings this dependent job only comparer. + // + // Maybe should a DependentJobDefinition type spawn? + + public static readonly DependentJobDefinitionEqualityComparer Instance = new(); + + public bool Equals(JobDefinition? x, JobDefinition? y) => + (x is null && y is null) || (x is not null && y is not null + && x.Type == y.Type && x.Type != typeof(DynamicJobFactory) + && x.Parameter == y.Parameter + //&& x.CronExpression == y.CronExpression + //&& x.TimeZone == y.TimeZone + && x.CustomName == y.CustomName + //&& x.IsStartupJob == y.IsStartupJob + ); + + public int GetHashCode(JobDefinition obj) => HashCode.Combine( + obj.Type, + obj.Parameter, + //obj.CronExpression, + //obj.TimeZone, + obj.CustomName + //obj.IsStartupJob + ); + } }