Skip to content

Commit

Permalink
Merge pull request #181 from alphacloud/releases/7.0.0
Browse files Browse the repository at this point in the history
version 7.0.0
  • Loading branch information
cd21h authored Feb 16, 2021
2 parents 43ebb5c + 3461d87 commit d6f103f
Show file tree
Hide file tree
Showing 22 changed files with 288 additions and 183 deletions.
5 changes: 2 additions & 3 deletions .build/definitions.cake
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
// ADDINS
#addin nuget:?package=Cake.Coveralls&version=0.10.2
#addin nuget:?package=Cake.FileHelpers&version=3.3.0
#addin nuget:?package=Cake.Issues&version=0.9.1
#addin nuget:?package=Cake.AppVeyor&version=4.0.0

// TOOLS
#tool nuget:?package=GitReleaseManager&version=0.11.0
#tool nuget:?package=GitVersion.CommandLine&version=5.6.4
#tool nuget:?package=GitVersion.CommandLine&version=5.6.6
#tool nuget:?package=coveralls.io&version=1.4.2
#tool nuget:?package=OpenCover&version=4.7.922
#tool nuget:?package=ReportGenerator&version=4.8.4
#tool nuget:?package=ReportGenerator&version=4.8.5


public class CodeCoverageSettings
Expand Down
8 changes: 6 additions & 2 deletions .build/tasks.cake
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,18 @@ Task("CleanPreviousTestResults")
DeleteFile(build.Paths.TestCoverageOutputFile);
DeleteFiles(build.Paths.ArtifactsDir + "/*.trx");
if (DirectoryExists(build.Paths.TestCoverageReportDir))
DeleteDirectory(build.Paths.TestCoverageReportDir, recursive: true);
DeleteDirectory(build.Paths.TestCoverageReportDir, new DeleteDirectorySettings
{
Force = true,
Recursive = true
});
});

Task("GenerateCoverageReport")
.WithCriteria<BuildInfo>((ctx, build) => build.IsLocal)
.Does<BuildInfo>(build =>
{
ReportGenerator(build.Paths.TestCoverageOutputFile, build.Paths.TestCoverageReportDir);
ReportGenerator((FilePath)build.Paths.TestCoverageOutputFile, build.Paths.TestCoverageReportDir);
});

Task("UploadCoverage")
Expand Down
28 changes: 25 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Install package via Nuget: `install-package Autofac.Extras.Quartz`

# Usage example

Autofac configuration for Quartz consists of two steps:
Autofac configuration for Quartz includes two steps:
1. Scheduler registration
2. Job registration

Expand All @@ -34,7 +34,29 @@ Both factory and schedulere are registered as singletones.

Optionally custom Quartz configuration can be passed using `ConfigurationProvider` property. Provider is callback which returns settings using `NameValueCollection`.

### Job scope configuration

Starting with version 7 `QuartzAutofacFactoryModule` provides a way to customize lifetime scope configuration for job. This can be done via `JobScopeConfigurator` parameter.

```csharp
cb.Register(_ => new ScopedDependency("global"))
.AsImplementedInterfaces()
.SingleInstance();

cb.RegisterModule(new QuartzAutofacFactoryModule {
JobScopeConfigurator = (builder, jobScopeTag) => {
// override dependency for job scope
builder.Register(_ => new ScopedDependency("job-local "+ DateTime.UtcNow.ToLongTimeString()))
.AsImplementedInterfaces()
.InstancePerMatchingLifetimeScope(jobScopeTag);

}
});
```
See [src/Samples/Shared/Bootstrap.cs](src/Samples/Shared/Bootstrap.cs) for details.

## Job registration

`QuartzAutofacJobsModule` scans given assemblies and registers all non-abstract implementors of `IJob` interface as transient instances.

```csharp
Expand All @@ -55,7 +77,7 @@ scheduler.Start();
```

## Sample projects
* See ``src/Samples/Console`` for .NetCore console application.
* ``src/Samples/Shared`` contains source code shared between samples.
* See [src/Samples/Console](src/Samples/Console/) for .NetCore console application.
* [src/Samples/Shared](src/Samples/Shared/) contains source code shared between samples.

TopShelf-based sample was removed since Topshelf.Quartz is not compatible with Quartz 3 as af now.
9 changes: 8 additions & 1 deletion src/Autofac.Extras.Quartz.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp90</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantArgumentNameForLiteralExpression/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=Full/@EntryIndexedValue">&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;Profile name="Full"&gt;&lt;AspOptimizeRegisterDirectives&gt;True&lt;/AspOptimizeRegisterDirectives&gt;&lt;HtmlReformatCode&gt;True&lt;/HtmlReformatCode&gt;&lt;CSArrangeThisQualifier&gt;True&lt;/CSArrangeThisQualifier&gt;&lt;RemoveCodeRedundancies&gt;True&lt;/RemoveCodeRedundancies&gt;&lt;CSUseAutoProperty&gt;True&lt;/CSUseAutoProperty&gt;&lt;CSMakeFieldReadonly&gt;True&lt;/CSMakeFieldReadonly&gt;&lt;CSUseVar&gt;&lt;BehavourStyle&gt;CAN_CHANGE_TO_IMPLICIT&lt;/BehavourStyle&gt;&lt;LocalVariableStyle&gt;IMPLICIT_EXCEPT_PRIMITIVE_TYPES&lt;/LocalVariableStyle&gt;&lt;ForeachVariableStyle&gt;ALWAYS_IMPLICIT&lt;/ForeachVariableStyle&gt;&lt;/CSUseVar&gt;&lt;CSOptimizeUsings&gt;&lt;OptimizeUsings&gt;True&lt;/OptimizeUsings&gt;&lt;EmbraceInRegion&gt;False&lt;/EmbraceInRegion&gt;&lt;RegionName&gt;&lt;/RegionName&gt;&lt;/CSOptimizeUsings&gt;&lt;CSShortenReferences&gt;True&lt;/CSShortenReferences&gt;&lt;CSReformatCode&gt;True&lt;/CSReformatCode&gt;&lt;CSharpFormatDocComments&gt;True&lt;/CSharpFormatDocComments&gt;&lt;CSReorderTypeMembers&gt;True&lt;/CSReorderTypeMembers&gt;&lt;VBOptimizeImports&gt;True&lt;/VBOptimizeImports&gt;&lt;VBShortenReferences&gt;True&lt;/VBShortenReferences&gt;&lt;VBReformatCode&gt;True&lt;/VBReformatCode&gt;&lt;VBFormatDocComments&gt;True&lt;/VBFormatDocComments&gt;&lt;JsInsertSemicolon&gt;True&lt;/JsInsertSemicolon&gt;&lt;JsReformatCode&gt;True&lt;/JsReformatCode&gt;&lt;JsFormatDocComments&gt;True&lt;/JsFormatDocComments&gt;&lt;CssAlphabetizeProperties&gt;True&lt;/CssAlphabetizeProperties&gt;&lt;CssReformatCode&gt;True&lt;/CssReformatCode&gt;&lt;XMLReformatCode&gt;True&lt;/XMLReformatCode&gt;&lt;CSUpdateFileHeader&gt;True&lt;/CSUpdateFileHeader&gt;&lt;CSCodeStyleAttributes ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" RemoveRedundantParentheses="True" AddMissingParentheses="False" ArrangeBraces="True" ArrangeAttributes="True" ArrangeArgumentsStyle="False" /&gt;&lt;CSMakeAutoPropertyGetOnly&gt;True&lt;/CSMakeAutoPropertyGetOnly&gt;&lt;CSArrangeQualifiers&gt;True&lt;/CSArrangeQualifiers&gt;&lt;CSFixBuiltinTypeReferences&gt;True&lt;/CSFixBuiltinTypeReferences&gt;&lt;RemoveCodeRedundanciesVB&gt;True&lt;/RemoveCodeRedundanciesVB&gt;&lt;FormatAttributeQuoteDescriptor&gt;True&lt;/FormatAttributeQuoteDescriptor&gt;&lt;CorrectVariableKindsDescriptor&gt;True&lt;/CorrectVariableKindsDescriptor&gt;&lt;VariablesToInnerScopesDescriptor&gt;True&lt;/VariablesToInnerScopesDescriptor&gt;&lt;StringToTemplatesDescriptor&gt;True&lt;/StringToTemplatesDescriptor&gt;&lt;RemoveRedundantQualifiersTs&gt;True&lt;/RemoveRedundantQualifiersTs&gt;&lt;OptimizeImportsTs&gt;True&lt;/OptimizeImportsTs&gt;&lt;OptimizeReferenceCommentsTs&gt;True&lt;/OptimizeReferenceCommentsTs&gt;&lt;PublicModifierStyleTs&gt;True&lt;/PublicModifierStyleTs&gt;&lt;ExplicitAnyTs&gt;True&lt;/ExplicitAnyTs&gt;&lt;TypeAnnotationStyleTs&gt;True&lt;/TypeAnnotationStyleTs&gt;&lt;RelativePathStyleTs&gt;True&lt;/RelativePathStyleTs&gt;&lt;/Profile&gt;</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/APPLY_ON_COMPLETION/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/DEFAULT_INTERNAL_MODIFIER/@EntryValue">Implicit</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/DEFAULT_PRIVATE_MODIFIER/@EntryValue">Implicit</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_BINARY_EXPRESSIONS_CHAIN/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/CASE_BLOCK_BRACES/@EntryValue">END_OF_LINE</s:String>
Expand Down Expand Up @@ -29,4 +33,7 @@ Copyright (c) 2014-$CURRENT_YEAR$ Alphacloud.Net&#xD;
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EUnitTestProvider_002EJavaScript_002EJavaScriptUnitTestProvidersSettingsMigration/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/Environment/UnitTesting/JavaScriptUnitTestProviders/BrowserId/@EntryValue">firefox</s:String>
<s:String x:Key="/Default/Environment/UnitTesting/JavaScriptUnitTestProviders/BrowserLocation/@EntryValue">C:\Program Files (x86)\Mozilla Firefox\firefox.exe</s:String>
<s:String x:Key="/Default/Environment/UnitTesting/JavaScriptUnitTestProviders/JasmineJsVersion/@EntryValue">2.0</s:String></wpf:ResourceDictionary>
<s:String x:Key="/Default/Environment/UnitTesting/JavaScriptUnitTestProviders/JasmineJsVersion/@EntryValue">2.0</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Alphacloud/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Autofac/@EntryIndexedValue">True</s:Boolean>
</wpf:ResourceDictionary>
25 changes: 17 additions & 8 deletions src/Autofac.Extras.Quartz/AutofacJobFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,32 @@ namespace Autofac.Extras.Quartz
[PublicAPI]
public class AutofacJobFactory : IJobFactory, IDisposable
{
[NotNull] readonly ILifetimeScope _lifetimeScope;
readonly ILifetimeScope _lifetimeScope;

[NotNull] readonly object _scopeTag;
readonly object _scopeTag;

readonly QuartzJobScopeConfigurator? _jobScopeConfigurator;

/// <summary>
/// Initializes a new instance of the <see cref="AutofacJobFactory" /> class.
/// </summary>
/// <param name="lifetimeScope">The lifetime scope.</param>
/// <param name="scopeTag">The tag to use for new scopes.</param>
/// <param name="jobScopeConfigurator">Configures job scope.</param>
/// <exception cref="ArgumentNullException">
/// <paramref name="lifetimeScope" /> or <paramref name="scopeTag" /> is
/// <see langword="null" />.
/// </exception>
public AutofacJobFactory([NotNull] ILifetimeScope lifetimeScope, [NotNull] object scopeTag)
public AutofacJobFactory(ILifetimeScope lifetimeScope, object scopeTag,
QuartzJobScopeConfigurator? jobScopeConfigurator)
{
_lifetimeScope = lifetimeScope ?? throw new ArgumentNullException(nameof(lifetimeScope));
_scopeTag = scopeTag ?? throw new ArgumentNullException(nameof(scopeTag));
_jobScopeConfigurator = jobScopeConfigurator;
}

internal ConcurrentDictionary<object, JobTrackingInfo> RunningJobs { get; } =
new ConcurrentDictionary<object, JobTrackingInfo>();
new();

/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
Expand Down Expand Up @@ -83,14 +88,18 @@ public void Dispose()
/// Error resolving exception. Original exception will be stored in
/// <see cref="Exception.InnerException" />.
/// </exception>
[NotNull]
public virtual IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
if (bundle == null) throw new ArgumentNullException(nameof(bundle));
if (scheduler == null) throw new ArgumentNullException(nameof(scheduler));

var jobDetail = bundle.JobDetail;
var nestedScope = _lifetimeScope.BeginLifetimeScope(_scopeTag);

// don't call nested container configuration unless custom configurator was specified
// this is have operation so try to skip it if possible.
var nestedScope = _jobScopeConfigurator != null
? _lifetimeScope.BeginLifetimeScope(_scopeTag, builder => _jobScopeConfigurator(builder, _scopeTag))
: _lifetimeScope.BeginLifetimeScope(_scopeTag);

IJob newJob;
try
Expand Down Expand Up @@ -131,7 +140,7 @@ protected virtual IJob ResolveJobInstance(ILifetimeScope nestedScope, IJobDetail
/// <summary>
/// Allows the the job factory to destroy/cleanup the job if needed.
/// </summary>
public void ReturnJob(IJob job)
public void ReturnJob(IJob? job)
{
if (job == null)
return;
Expand All @@ -143,7 +152,7 @@ public void ReturnJob(IJob job)
}
else
{
trackingInfo.Scope?.Dispose();
trackingInfo.Scope.Dispose();
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/Autofac.Extras.Quartz/AutofacSchedulerFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ namespace Autofac.Extras.Quartz
[PublicAPI]
public class AutofacSchedulerFactory : StdSchedulerFactory
{
[NotNull] readonly AutofacJobFactory _jobFactory;
readonly AutofacJobFactory _jobFactory;

/// <summary>
/// Initializes a new instance of the <see cref="T:Quartz.Impl.StdSchedulerFactory" /> class.
/// </summary>
/// <param name="jobFactory">Job factory.</param>
/// <exception cref="ArgumentNullException"><paramref name="jobFactory" /> is <see langword="null" />.</exception>
public AutofacSchedulerFactory([NotNull] AutofacJobFactory jobFactory)
public AutofacSchedulerFactory(AutofacJobFactory jobFactory)
{
_jobFactory = jobFactory ?? throw new ArgumentNullException(nameof(jobFactory));
}
Expand All @@ -40,7 +40,7 @@ public AutofacSchedulerFactory([NotNull] AutofacJobFactory jobFactory)
/// <param name="props">The properties.</param>
/// <param name="jobFactory">Job factory</param>
/// <exception cref="ArgumentNullException"><paramref name="jobFactory" /> is <see langword="null" />.</exception>
public AutofacSchedulerFactory(NameValueCollection props, [NotNull] AutofacJobFactory jobFactory)
public AutofacSchedulerFactory(NameValueCollection props, AutofacJobFactory jobFactory)
: base(props)
{
_jobFactory = jobFactory ?? throw new ArgumentNullException(nameof(jobFactory));
Expand Down
38 changes: 30 additions & 8 deletions src/Autofac.Extras.Quartz/QuartzAutofacFactoryModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,24 @@ namespace Autofac.Extras.Quartz
using global::Quartz.Spi;
using JetBrains.Annotations;


/// <summary>
/// Provides additional configuration to Quartz scheduler.
/// </summary>
/// <param name="componentContext"></param>
/// <returns>Quartz configuration settings.</returns>
public delegate NameValueCollection QuartzConfigurationProvider(IComponentContext componentContext);

/// <summary>
/// Configures scheduler job scope.
/// </summary>
/// <remarks>
/// Used to override global container registrations at job scope.
/// </remarks>
/// <param name="containerBuilder">Autofac container builder.</param>
/// <param name="scopeTag">Job scope tag.</param>
public delegate void QuartzJobScopeConfigurator(ContainerBuilder containerBuilder, object scopeTag);

/// <summary>
/// Registers <see cref="ISchedulerFactory" /> and default <see cref="IScheduler" />.
/// </summary>
Expand All @@ -25,9 +43,9 @@ public class QuartzAutofacFactoryModule : Module
/// <summary>
/// Default name for nested lifetime scope.
/// </summary>
public const string LifetimeScopeName = "quartz.job";
public static readonly string LifetimeScopeName = "quartz.job";

readonly string _lifetimeScopeName;
readonly string _lifetimeScopeTag;

/// <summary>
/// Initializes a new instance of the <see cref="QuartzAutofacFactoryModule" /> class with a default lifetime scope
Expand All @@ -42,11 +60,11 @@ public QuartzAutofacFactoryModule()
/// <summary>
/// Initializes a new instance of the <see cref="QuartzAutofacFactoryModule" /> class.
/// </summary>
/// <param name="lifetimeScopeName">Name of the lifetime scope to wrap job resolution and execution.</param>
/// <param name="lifetimeScopeTag">Tag of the lifetime scope to wrap job resolution and execution.</param>
/// <exception cref="System.ArgumentNullException">lifetimeScopeName</exception>
public QuartzAutofacFactoryModule([NotNull] string lifetimeScopeName)
public QuartzAutofacFactoryModule(string lifetimeScopeTag)
{
_lifetimeScopeName = lifetimeScopeName ?? throw new ArgumentNullException(nameof(lifetimeScopeName));
_lifetimeScopeTag = lifetimeScopeTag ?? throw new ArgumentNullException(nameof(lifetimeScopeTag));
}

/// <summary>
Expand All @@ -55,8 +73,12 @@ public QuartzAutofacFactoryModule([NotNull] string lifetimeScopeName)
/// <para>See http://quartz-scheduler.org/documentation/quartz-2.x/configuration/ for settings description.</para>
/// <seealso cref="StdSchedulerFactory" /> for some configuration property names.
/// </summary>
[CanBeNull]
public Func<IComponentContext, NameValueCollection> ConfigurationProvider { get; set; }
public QuartzConfigurationProvider? ConfigurationProvider { get; set; }

/// <summary>
/// Allows to override job scope registrations.
/// </summary>
public QuartzJobScopeConfigurator? JobScopeConfigurator { get; set; }

/// <summary>
/// Override to add registrations to the container.
Expand All @@ -70,7 +92,7 @@ public QuartzAutofacFactoryModule([NotNull] string lifetimeScopeName)
/// </param>
protected override void Load(ContainerBuilder builder)
{
builder.Register(c => new AutofacJobFactory(c.Resolve<ILifetimeScope>(), _lifetimeScopeName))
builder.Register(c => new AutofacJobFactory(c.Resolve<ILifetimeScope>(), _lifetimeScopeTag, JobScopeConfigurator))
.AsSelf()
.As<IJobFactory>()
.SingleInstance();
Expand Down
12 changes: 6 additions & 6 deletions src/Autofac.Extras.Quartz/QuartzAutofacJobsModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace Autofac.Extras.Quartz
using System.Runtime.CompilerServices;
using global::Quartz;
using JetBrains.Annotations;
// ReSharper disable once RedundantNameQualifier
using Module = Autofac.Module;

/// <summary>
Expand All @@ -29,15 +30,15 @@ namespace Autofac.Extras.Quartz
[PublicAPI]
public class QuartzAutofacJobsModule : Module
{
[NotNull] readonly Assembly[] _assembliesToScan;
readonly Assembly[] _assembliesToScan;


/// <summary>
/// Initializes a new instance of the <see cref="QuartzAutofacJobsModule" /> class.
/// </summary>
/// <param name="assembliesToScan">The assemblies to scan for jobs.</param>
/// <exception cref="System.ArgumentNullException">assembliesToScan</exception>
public QuartzAutofacJobsModule([NotNull] params Assembly[] assembliesToScan)
public QuartzAutofacJobsModule(params Assembly[] assembliesToScan)
{
_assembliesToScan = assembliesToScan ?? throw new ArgumentNullException(nameof(assembliesToScan));
}
Expand All @@ -63,8 +64,7 @@ public QuartzAutofacJobsModule([NotNull] params Assembly[] assembliesToScan)
/// Job registration filter callback.
/// </summary>
/// <seealso cref="JobRegistrationFilter" />
[CanBeNull]
public JobRegistrationFilter JobFilter { get; set; }
public JobRegistrationFilter? JobFilter { get; set; }

/// <summary>
/// Override to add registrations to the container.
Expand All @@ -87,12 +87,12 @@ protected override void Load(ContainerBuilder builder)
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool FilterJob([NotNull] Type jobType)
bool FilterJob(Type jobType)
{
return JobFilter?.Invoke(jobType) ?? true;
}

private static bool IsAbstract([NotNull] Type type)
static bool IsAbstract(Type type)
{
return type.IsAbstract;
}
Expand Down
Loading

0 comments on commit d6f103f

Please sign in to comment.