├── .gitattributes
├── .github
└── workflows
│ └── sonarcloud.yml
├── .gitignore
├── .nuget
├── NuGet.exe
├── packages.config
└── packages.lock.json
├── Directory.Build.props
├── Hangfire.Autofac.sln
├── LICENSE
├── NuGet.config
├── README.md
├── appveyor.yml
├── build.bat
├── nuspecs
├── Hangfire.Autofac.nuspec
└── icon.png
├── psake-project.ps1
├── src
├── Directory.Build.props
├── Hangfire.Autofac
│ ├── AutofacBootstrapperConfigurationExtensions.cs
│ ├── AutofacJobActivator.cs
│ ├── GlobalConfigurationExtensions.cs
│ ├── Hangfire.Autofac.csproj
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── RegistrationExtensions.cs
│ └── packages.lock.json
└── SharedAssemblyInfo.cs
└── tests
├── Directory.Build.props
└── Hangfire.Autofac.Tests
├── AutofacBootstrapperConfigurationExtensionsFacts.cs
├── AutofacJobActivatorTests.cs
├── GlobalConfigurationExtensionsFacts.cs
├── Hangfire.Autofac.Tests.csproj
└── packages.lock.json
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp text
6 | *.sln merge=union text eol=crlf
7 | *.csproj merge=union text eol=crlf
8 | *.vbproj merge=union text eol=crlf
9 | *.fsproj merge=union text eol=crlf
10 | *.dbproj merge=union text eol=crlf
11 |
12 | # Source code
13 | *.bat text
14 | *.ps1 text
15 | *.nuspec text
16 |
17 | # Documentation
18 | *.md text
19 | *.txt text
20 | *.manifest text
21 | COPYING text
22 | COPYING.LESSER text
23 |
24 | # Configs
25 | *.config text
26 | .editorconfig text
27 | .gitattributes text
28 | .gitignore text
29 | *.yml text
30 | *.DotSettings text
--------------------------------------------------------------------------------
/.github/workflows/sonarcloud.yml:
--------------------------------------------------------------------------------
1 | name: SonarCloud
2 | on:
3 | push:
4 | branches:
5 | - main
6 | - dev
7 | pull_request:
8 | types: [opened, synchronize, reopened]
9 | jobs:
10 | build:
11 | name: Build and analyze
12 | runs-on: windows-latest
13 | steps:
14 | - name: Set up JDK 17
15 | uses: actions/setup-java@v4
16 | with:
17 | java-version: 17
18 | distribution: 'zulu' # Alternative distribution options are available.
19 | - uses: actions/checkout@v4
20 | with:
21 | fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
22 | - name: Cache SonarCloud packages
23 | uses: actions/cache@v4
24 | with:
25 | path: ~\sonar\cache
26 | key: ${{ runner.os }}-sonar
27 | restore-keys: ${{ runner.os }}-sonar
28 | - name: Cache NuGet packages
29 | uses: actions/cache@v4
30 | env:
31 | ZSTD_CLEVEL: 1
32 | with:
33 | path: ~/.nuget/TrustedPackages
34 | key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
35 | restore-keys: ${{ runner.os }}-nuget-
36 | - name: Cache SonarCloud scanner
37 | id: cache-sonar-scanner
38 | uses: actions/cache@v4
39 | with:
40 | path: .\.sonar\scanner
41 | key: ${{ runner.os }}-sonar-scanner
42 | restore-keys: ${{ runner.os }}-sonar-scanner
43 | - name: Install SonarCloud scanner
44 | if: steps.cache-sonar-scanner.outputs.cache-hit != 'true'
45 | shell: powershell
46 | run: |
47 | New-Item -Path .\.sonar\scanner -ItemType Directory
48 | dotnet tool update dotnet-sonarscanner --tool-path .\.sonar\scanner
49 | dotnet tool update JetBrains.dotCover.GlobalTool --tool-path .\.sonar\scanner
50 | - name: Build and analyze
51 | env:
52 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
53 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
54 | shell: powershell
55 | run: |
56 | .\.sonar\scanner\dotnet-sonarscanner begin /k:"HangfireIO_Hangfire.Autofac" /o:"hangfireio" /d:sonar.token="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.dotcover.reportsPaths=dotCover.Output.html /d:sonar.scanner.scanAll=false
57 | .\.sonar\scanner\dotnet-dotcover test -f net6.0 --dcReportType=HTML
58 | .\.sonar\scanner\dotnet-sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}"
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.sln.docstates
8 |
9 | # Build results
10 | [Dd]ebug/
11 | [Dd]ebugPublic/
12 | [Rr]elease/
13 | x64/
14 | build/
15 | bld/
16 | [Bb]in/
17 | [Oo]bj/
18 |
19 | # Visual Studio cache/options directory
20 | .vs/
21 |
22 | # Cake files
23 | tools
24 |
25 | # MSTest test Results
26 | [Tt]est[Rr]esult*/
27 | [Bb]uild[Ll]og.*
28 |
29 | #NUNIT
30 | *.VisualState.xml
31 | TestResult.xml
32 |
33 | # Build Results of an ATL Project
34 | [Dd]ebugPS/
35 | [Rr]eleasePS/
36 | dlldata.c
37 |
38 | *_i.c
39 | *_p.c
40 | *_i.h
41 | *.ilk
42 | *.meta
43 | *.obj
44 | *.pch
45 | *.pdb
46 | *.pgc
47 | *.pgd
48 | *.rsp
49 | *.sbr
50 | *.tlb
51 | *.tli
52 | *.tlh
53 | *.tmp
54 | *.tmp_proj
55 | *.log
56 | *.vspscc
57 | *.vssscc
58 | .builds
59 | *.pidb
60 | *.svclog
61 | *.scc
62 |
63 | # Chutzpah Test files
64 | _Chutzpah*
65 |
66 | # Visual C++ cache files
67 | ipch/
68 | *.aps
69 | *.ncb
70 | *.opensdf
71 | *.sdf
72 | *.cachefile
73 |
74 | # Visual Studio profiler
75 | *.psess
76 | *.vsp
77 | *.vspx
78 |
79 | # TFS 2012 Local Workspace
80 | $tf/
81 |
82 | # Guidance Automation Toolkit
83 | *.gpState
84 |
85 | # ReSharper is a .NET coding add-in
86 | _ReSharper*/
87 | *.[Rr]e[Ss]harper
88 | *.DotSettings.user
89 |
90 | # JustCode is a .NET coding addin-in
91 | .JustCode
92 |
93 | # TeamCity is a build add-in
94 | _TeamCity*
95 |
96 | # DotCover is a Code Coverage Tool
97 | *.dotCover
98 |
99 | # NCrunch
100 | *.ncrunch*
101 | _NCrunch_*
102 | .*crunch*.local.xml
103 |
104 | # MightyMoose
105 | *.mm.*
106 | AutoTest.Net/
107 |
108 | # Web workbench (sass)
109 | .sass-cache/
110 |
111 | # Installshield output folder
112 | [Ee]xpress/
113 |
114 | # DocProject is a documentation generator add-in
115 | DocProject/buildhelp/
116 | DocProject/Help/*.HxT
117 | DocProject/Help/*.HxC
118 | DocProject/Help/*.hhc
119 | DocProject/Help/*.hhk
120 | DocProject/Help/*.hhp
121 | DocProject/Help/Html2
122 | DocProject/Help/html
123 |
124 | # Click-Once directory
125 | publish/
126 |
127 | # Publish Web Output
128 | *.[Pp]ublish.xml
129 | *.azurePubxml
130 |
131 | # NuGet Packages Directory
132 | packages/
133 | ## TODO: If the tool you use requires repositories.config uncomment the next line
134 | #!packages/repositories.config
135 |
136 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
137 | # This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented)
138 | !packages/build/
139 |
140 | # Windows Azure Build Output
141 | csx/
142 | *.build.csdef
143 |
144 | # Windows Store app package directory
145 | AppPackages/
146 |
147 | # Others
148 | sql/
149 | *.Cache
150 | ClientBin/
151 | [Ss]tyle[Cc]op.*
152 | ~$*
153 | *~
154 | *.dbmdl
155 | *.dbproj.schemaview
156 | *.pfx
157 | *.publishsettings
158 | node_modules/
159 |
160 | # RIA/Silverlight projects
161 | Generated_Code/
162 |
163 | # Backup & report files from converting an old project file to a newer
164 | # Visual Studio version. Backup files are not needed, because we have git ;-)
165 | _UpgradeReport_Files/
166 | Backup*/
167 | UpgradeLog*.XML
168 | UpgradeLog*.htm
169 |
170 | # SQL Server files
171 | *.mdf
172 | *.ldf
173 |
174 | # Business Intelligence projects
175 | *.rdl.data
176 | *.bim.layout
177 | *.bim_*.settings
178 |
179 | # Microsoft Fakes
180 | FakesAssemblies/
181 |
182 | .idea/*
183 | dotCover.Output*
184 |
--------------------------------------------------------------------------------
/.nuget/NuGet.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HangfireIO/Hangfire.Autofac/066855715f5582da2218b16e9b491fe246fa4769/.nuget/NuGet.exe
--------------------------------------------------------------------------------
/.nuget/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.nuget/packages.lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 1,
3 | "dependencies": {
4 | "Any,Version=v0.0": {
5 | "Hangfire.Build": {
6 | "type": "Direct",
7 | "requested": "[0.5.0, 0.5.0]",
8 | "resolved": "0.5.0",
9 | "contentHash": "4yRCdMaDr6cyFRmCvpFO8kBMV57KPOofugaHOsjkDEDw+G/BCGWOdrpXfkAeTEtZBPUv2jS0PYmVNK5680KxXQ=="
10 | },
11 | "psake": {
12 | "type": "Direct",
13 | "requested": "[4.4.1, 4.4.1]",
14 | "resolved": "4.4.1",
15 | "contentHash": "Hn5kdGPEoapi+wAAjaGjKEZVnuYp7fUrPK3IivLYG6Bn4adhd8l+KXXPMEmte41RmrLvfV7XGZa9KsSTc0gjDA=="
16 | }
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | true
4 | true
5 |
6 |
7 |
8 | true
9 |
10 |
--------------------------------------------------------------------------------
/Hangfire.Autofac.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26510.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{9058456C-F07D-4BD2-8E1C-9AAD8D836D81}"
7 | ProjectSection(SolutionItems) = preProject
8 | .nuget\NuGet.exe = .nuget\NuGet.exe
9 | .nuget\packages.config = .nuget\packages.config
10 | EndProjectSection
11 | EndProject
12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hangfire.Autofac", "src\Hangfire.Autofac\Hangfire.Autofac.csproj", "{C75F15D3-9EA8-4B13-9FCA-D7B22AC1D92F}"
13 | EndProject
14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hangfire.Autofac.Tests", "tests\Hangfire.Autofac.Tests\Hangfire.Autofac.Tests.csproj", "{42957241-3105-4859-B6AB-5962C1F0BCD5}"
15 | EndProject
16 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{4957DA4F-B3DB-4DA4-9642-C54A716B68FD}"
17 | ProjectSection(SolutionItems) = preProject
18 | appveyor.yml = appveyor.yml
19 | build.bat = build.bat
20 | psake-project.ps1 = psake-project.ps1
21 | src\Directory.Build.props = src\Directory.Build.props
22 | EndProjectSection
23 | EndProject
24 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "nuspecs", "nuspecs", "{1AC4778F-330D-4A4B-B680-C9DA7A7E612B}"
25 | ProjectSection(SolutionItems) = preProject
26 | nuspecs\Hangfire.Autofac.nuspec = nuspecs\Hangfire.Autofac.nuspec
27 | EndProjectSection
28 | EndProject
29 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{5742DC62-57DF-4C3C-9F69-DA68058E9C38}"
30 | ProjectSection(SolutionItems) = preProject
31 | tests\Directory.Build.props = tests\Directory.Build.props
32 | EndProjectSection
33 | EndProject
34 | Global
35 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
36 | Debug|Any CPU = Debug|Any CPU
37 | Release|Any CPU = Release|Any CPU
38 | EndGlobalSection
39 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
40 | {C75F15D3-9EA8-4B13-9FCA-D7B22AC1D92F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
41 | {C75F15D3-9EA8-4B13-9FCA-D7B22AC1D92F}.Debug|Any CPU.Build.0 = Debug|Any CPU
42 | {C75F15D3-9EA8-4B13-9FCA-D7B22AC1D92F}.Release|Any CPU.ActiveCfg = Release|Any CPU
43 | {C75F15D3-9EA8-4B13-9FCA-D7B22AC1D92F}.Release|Any CPU.Build.0 = Release|Any CPU
44 | {42957241-3105-4859-B6AB-5962C1F0BCD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
45 | {42957241-3105-4859-B6AB-5962C1F0BCD5}.Debug|Any CPU.Build.0 = Debug|Any CPU
46 | {42957241-3105-4859-B6AB-5962C1F0BCD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
47 | {42957241-3105-4859-B6AB-5962C1F0BCD5}.Release|Any CPU.Build.0 = Release|Any CPU
48 | EndGlobalSection
49 | GlobalSection(SolutionProperties) = preSolution
50 | HideSolutionNode = FALSE
51 | EndGlobalSection
52 | GlobalSection(ExtensibilityGlobals) = postSolution
53 | SolutionGuid = {ACFC4F30-A606-4691-8C46-A8E8366DFC22}
54 | EndGlobalSection
55 | GlobalSection(NestedProjects) = preSolution
56 | {42957241-3105-4859-B6AB-5962C1F0BCD5} = {5742DC62-57DF-4C3C-9F69-DA68058E9C38}
57 | EndGlobalSection
58 | EndGlobal
59 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Hangfire OÜ
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/NuGet.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | Microsoft;aspnet;HangfireIO;odinserj;Autofac;alexmg;xunit;jamesnk;kzu;castleproject;psake
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Hangfire.Autofac
3 |
4 | [](https://www.nuget.org/packages/Hangfire.Autofac) [](https://ci.appveyor.com/project/hangfireio/hangfire-autofac) [](https://sonarcloud.io/summary/new_code?id=HangfireIO_Hangfire.Autofac) [](https://sonarcloud.io/summary/new_code?id=HangfireIO_Hangfire.Autofac) [](https://sonarcloud.io/summary/new_code?id=HangfireIO_Hangfire.Autofac) [](https://sonarcloud.io/summary/new_code?id=HangfireIO_Hangfire.Autofac)
5 |
6 | [Autofac](https://autofac.org) integration for [Hangfire](https://www.hangfire.io). Provides an implementation of the `JobActivator` class and registration extensions, allowing you to use Autofac container to **resolve job type instances** as well as **control the lifetime** of the all related dependencies.
7 |
8 | *Hangfire.Autofac* resolves service instances using a child, tagged [lifetime scope](https://docs.autofac.org/en/latest/lifetime/index.html). A child scope is created and disposed each time when background job processing takes place, so you have precise control of your service's lifetime, including **shared instances** and **deterministic disposal**.
9 |
10 | ## Installation
11 |
12 | *Hangfire.Autofac* is available as a NuGet Package. Type the following command into NuGet Package Manager Console window to install it:
13 |
14 | ```
15 | > dotnet add package Hangfire.Autofac
16 | ```
17 |
18 | ## Usage
19 |
20 | The package provides an extension methods for the `IGlobalConfiguration` interface, so you can enable Autofac integration using the `GlobalConfiguration` class:
21 |
22 | ```csharp
23 | var builder = new ContainerBuilder();
24 | // builder.Register...
25 |
26 | GlobalConfiguration.Configuration.UseAutofacActivator(builder.Build());
27 | ```
28 |
29 | After invoking the `UseAutofacActivator` method, Autofac-based implementation of the `JobActivator` class will be used to resolve job type instances during the background job processing.
30 |
31 | ### Custom Scope Configuration
32 |
33 | Starting from version 2.7.0 it is possible to define a custom scope configuration action and pass background job-related data to the service registration logic, like identifier, parameters and so on.
34 |
35 | ```csharp
36 | GlobalConfiguration.Configuration.UseAutofacActivator(builder.Build(), (builder, context) =>
37 | {
38 | var tenantId = context.GetJobParameter("TenantId", allowStale: true);
39 | builder.Register(provider => new MultiTenantDatabase(tenantId));
40 | });
41 | ```
42 |
43 | ### Shared Components
44 |
45 | Sometimes it is required to share the same service instance for different components, such as database connection, unit of work, etc. *Hangfire.Autofac* allows you to share them in a scope, limited to the **current** background job processing, just call the `InstancePerBackgroundJob` method in your component registration logic:
46 |
47 | ```csharp
48 | builder.RegisterType().InstancePerBackgroundJob();
49 | ```
50 |
51 | ### Non-tagged scopes
52 |
53 | Whenever the scopes in `AutofacActivator` are created, by default they are created using tag `BackgroundJobScope`. There might be a scenario when it is needed not to use tagged scopes though. This might be a case if it is required to have a new instance of every service for each lifetime scope (in Hangfire it would be for every job). To disable tagged scopes you can use a flag `useTaggedLifetimeScope` during initialization of `AutofacActivator` for Hangfire.
54 |
55 | ```csharp
56 | var builder = new ContainerBuilder();
57 | // builder.Register...
58 |
59 | GlobalConfiguration.Configuration.UseAutofacActivator(builder.Build(), false);
60 | ```
61 |
62 | Then you can register services by using `InstancePerLifetimeScope` and expect them to work like intended.
63 |
64 | ```csharp
65 | builder.RegisterType().InstancePerLifetimeScope();
66 | ```
67 |
68 | ### Deterministic Disposal
69 |
70 | The *child lifetime scope* is disposed as soon as current background job is performed, successfully or with an exception. Since *Autofac* automatically disposes all the components that implement the `IDisposable` interface (if this feature not disabled), all of the resolved components will be disposed *if appropriate*.
71 |
72 | For example, the following components will be **disposed automatically**:
73 |
74 | ```csharp
75 | builder.RegisterType();
76 | builder.RegisterType().InstancePerDependency();
77 | builder.RegisterType().InstancePerBackgroundJob();
78 | ```
79 |
80 | And the following components **will not be disposed**:
81 |
82 | ```csharp
83 | builder.RegisterType().SingleInstance();
84 | builder.RegisterType().ExternallyOwned();
85 | ```
86 |
87 | Please refer to the Autofac documentation to learn more about [Automatic Disposal](https://docs.autofac.org/en/latest/lifetime/disposal.html#automatic-disposal) feature.
88 |
89 | ### Registering With Multiple Lifetime Scopes
90 |
91 | Services registered with tagged lifetime scopes (eg `InstancePerBackgroundJob`, Autofac's `InstancePerRequest` or a scope your specific application requires) will not resolve outside of these named scopes, a common situation is when using Hangfire in an ASP.NET web application. In these situations you must register all your lifetimescopes together if you want the services to be resolved from any of the scopes. Hangfire.Autofac exposes it's lifetime tag and an overload of `InstancePerBackgroundJob` to help you do this.
92 |
93 | To register a service with both Autofac's PerRequest and Hangfire's PerBackgroundJob you could do any of the following:
94 |
95 | Passing Hangfire's scope tag to Autofac's `InstancePerHttpRequest`:
96 | ```csharp
97 | builder.RegisterType().InstancePerHttpRequest(AutofacJobActivator.LifetimeScopeTag);
98 | ```
99 |
100 | From Autofac 3.4.0 Autofac exposed their lifetime tag, `MatchingScopeLifetimeTags.RequestLifetimeScopeTag`, which can be used with `InstancePerBackgroundJob`:
101 | ```csharp
102 | builder.RegisterType().InstancePerBackgroundJob(MatchingScopeLifetimeTags.RequestLifetimeScopeTag);
103 | ```
104 |
105 | Both scope tags can also be used directly with Autofac's `InstancePerMatchingLifetimeScope`
106 | ```csharp
107 | var requestTag = MatchingScopeLifetimeTags.RequestLifetimeScopeTag;
108 | var jobTag = AutofacJobActivator.LifetimeScopeTag;
109 | builder.RegisterType().InstancePerMatchingLifetimeScope(requestTag, jobTag);
110 | ```
111 |
112 | ### Mixed Lifetime Scopes
113 |
114 | Beaware that if you are using multiple lifetime scopes to share services that all dependencies of those services need to be similarly registered. For example:
115 |
116 | ```csharp
117 | public class WebOnlyService(){ ... }
118 | public class SharedService(WebOnlyService){ ... }
119 |
120 | builder.RegisterType().InstancePerRequest();
121 | builder.RegisterType().InstancePerMatchingLifetimeScope(requestTag, jobTag);
122 | ```
123 |
124 | Attempting to resolve `SharedService` from a background job will throw an exception as Autofac will need to resolve `WebOnlyService` outside of a `RequestLifetimeScope`.
125 |
126 | Also be aware that many web related properties that you may be using such as `HttpContext.Current` **will be unavailable**.
127 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | # AppVeyor CI build file, https://ci.appveyor.com/project/odinserj/hangfire-autofac
2 |
3 | # Notes:
4 | # - Minimal appveyor.yml file is an empty file. All sections are optional.
5 | # - Indent each level of configuration with 2 spaces. Do not use tabs!
6 | # - All section names are case-sensitive.
7 | # - Section names should be unique on each level.
8 |
9 | #---------------------------------#
10 | # environment configuration #
11 | #---------------------------------#
12 |
13 | # Please don't edit it manually, use the `build.bat version` command instead.
14 | version: 2.7.0-build-0{build}
15 |
16 | image: Visual Studio 2022
17 |
18 | environment:
19 | SIGNPATH_API_TOKEN:
20 | secure: dPSXpwedaiJbmsEWuKXVcqQrWHh1fqBelWRFUYwlN6XkcE1UjmXkZMMAxaDv7o5O
21 |
22 | #---------------------------------#
23 | # build configuration #
24 | #---------------------------------#
25 |
26 | before_build:
27 | - pwsh: Install-PSResource -Name SignPath -TrustRepository
28 |
29 | build_script: build.bat sign
30 |
31 | #---------------------------------#
32 | # tests configuration #
33 | #---------------------------------#
34 |
35 | test: off
36 |
37 | #---------------------------------#
38 | # artifacts configuration #
39 | #---------------------------------#
40 |
41 | artifacts:
42 | - path: 'build\*.nupkg'
43 | - path: 'build\*.zip'
44 |
45 | deploy:
46 | - provider: NuGet
47 | api_key:
48 | secure: RCM2ZkVmO5joy6xWzukyBRu6Wdhma5NBlCjgaaM6YywfO+lJJy0lCpK5Fp0fGDSM
49 | on:
50 | appveyor_repo_tag: true
51 |
--------------------------------------------------------------------------------
/build.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | .nuget\NuGet.exe restore .nuget\packages.config -OutputDirectory packages -UseLockFile -LockedMode -NoHttpCache || exit /b 666
3 | pwsh.exe -NoProfile -ExecutionPolicy RemoteSigned -Command "& {Import-Module '.\packages\psake.*\tools\psake.psm1'; invoke-psake .\psake-project.ps1 %*; if ($psake.build_success -eq $false) { exit 1 } else { exit 0 }; }"
4 | exit /B %errorlevel%
--------------------------------------------------------------------------------
/nuspecs/Hangfire.Autofac.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Hangfire.Autofac
5 | %version%
6 | Hangfire Autofac Integration
7 | Sergey Odinokov
8 | HangfireIO, odinserj
9 | https://github.com/HangfireIO/Hangfire.Autofac
10 |
11 | MIT
12 | icon.png
13 | Autofac IoC Container integration support for Hangfire (background job framework for .NET applications).
14 | © 2014-2025 Hangfire OÜ
15 | Hangfire Autofac IoC Integration
16 | README.md
17 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/nuspecs/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HangfireIO/Hangfire.Autofac/066855715f5582da2218b16e9b491fe246fa4769/nuspecs/icon.png
--------------------------------------------------------------------------------
/psake-project.ps1:
--------------------------------------------------------------------------------
1 | Include "packages\Hangfire.Build.0.5.0\tools\psake-common.ps1"
2 |
3 | Task Default -Depends Pack
4 |
5 | Task Test -Depends Compile -Description "Run unit and integration tests." {
6 | Exec { dotnet test -c release --no-build "tests\Hangfire.Autofac.Tests" }
7 | }
8 |
9 | Task Collect -Depends Test -Description "Copy all artifacts to the build folder." {
10 | Collect-Assembly "Hangfire.Autofac" "net45"
11 | Collect-Assembly "Hangfire.Autofac" "netstandard1.3"
12 | Collect-Assembly "Hangfire.Autofac" "netstandard2.0"
13 | Collect-File "LICENSE"
14 | Collect-File "README.md"
15 | }
16 |
17 | Task Pack -Depends Collect -Description "Create NuGet packages and archive files." {
18 | $version = Get-PackageVersion
19 |
20 | Create-Package "Hangfire.Autofac" $version
21 | Create-Archive "Hangfire.Autofac-$version"
22 | }
23 |
24 | Task Sign -Depends Pack -Description "Sign artifacts." {
25 | $version = Get-PackageVersion
26 |
27 | Sign-ArchiveContents "Hangfire.Autofac-$version" "hangfire"
28 | }
--------------------------------------------------------------------------------
/src/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | false
6 | true
7 | embedded
8 | true
9 | false
10 |
11 |
12 |
13 | true
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | true
27 | latest
28 | All
29 | true
30 |
31 |
--------------------------------------------------------------------------------
/src/Hangfire.Autofac/AutofacBootstrapperConfigurationExtensions.cs:
--------------------------------------------------------------------------------
1 | #if NET45
2 | using System;
3 | using Autofac;
4 |
5 | // ReSharper disable once CheckNamespace
6 | namespace Hangfire
7 | {
8 | public static class AutofacBootstrapperConfigurationExtensions
9 | {
10 | ///
11 | /// Tells bootstrapper to use the specified Autofac
12 | /// lifetime scope as a global job activator.
13 | ///
14 | /// Configuration
15 | /// Autofac lifetime scope that will be used to activate jobs
16 | /// should tagged lifetimeScopes be used
17 | [Obsolete("Please use `GlobalConfiguration.Configuration.UseAutofacActivator` method instead. Will be removed in version 2.0.0.")]
18 | public static void UseAutofacActivator(
19 | this IBootstrapperConfiguration configuration,
20 | ILifetimeScope lifetimeScope, bool useTaggedLifetimeScope = true)
21 | {
22 | if (configuration == null) throw new ArgumentNullException(nameof(configuration));
23 | configuration.UseActivator(new AutofacJobActivator(lifetimeScope, useTaggedLifetimeScope));
24 | }
25 | }
26 | }
27 | #endif
--------------------------------------------------------------------------------
/src/Hangfire.Autofac/AutofacJobActivator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Autofac;
3 | using Hangfire.Annotations;
4 |
5 | // ReSharper disable once CheckNamespace
6 | namespace Hangfire
7 | {
8 | ///
9 | /// Hangfire Job Activator based on Autofac IoC Container.
10 | ///
11 | public class AutofacJobActivator : JobActivator
12 | {
13 | ///
14 | /// Tag used in setting up per-job lifetime scope registrations.
15 | ///
16 | public static readonly object LifetimeScopeTag = "BackgroundJobScope";
17 |
18 | private readonly ILifetimeScope _lifetimeScope;
19 | #if !NET45
20 | private readonly Action _scopeConfigurationAction;
21 | #endif
22 | private readonly bool _useTaggedLifetimeScope;
23 |
24 | ///
25 | /// Initializes a new instance of the
26 | /// class with the given Autofac Lifetime Scope.
27 | ///
28 | /// Container that will be used to create instance
29 | /// of classes during job activation process.
30 | /// Should the Container use Tag
31 | /// BackgroundJobScope to resolve dependencies or create new Scope on each job
32 | public AutofacJobActivator([NotNull] ILifetimeScope lifetimeScope, bool useTaggedLifetimeScope = true)
33 | {
34 | _lifetimeScope = lifetimeScope ?? throw new ArgumentNullException(nameof(lifetimeScope));
35 | _useTaggedLifetimeScope = useTaggedLifetimeScope;
36 | }
37 |
38 | #if !NET45
39 | public AutofacJobActivator(
40 | [NotNull] ILifetimeScope lifetimeScope,
41 | [CanBeNull] Action scopeConfigurationAction,
42 | bool useTaggedLifetimeScope = true)
43 | {
44 | _lifetimeScope = lifetimeScope ?? throw new ArgumentNullException(nameof(lifetimeScope));
45 | _scopeConfigurationAction = scopeConfigurationAction;
46 | _useTaggedLifetimeScope = useTaggedLifetimeScope;
47 | }
48 | #endif
49 |
50 | ///
51 | public override object ActivateJob(Type jobType)
52 | {
53 | return _lifetimeScope.Resolve(jobType);
54 | }
55 |
56 | #if NET45
57 | public override JobActivatorScope BeginScope()
58 | {
59 | return new AutofacScope(_useTaggedLifetimeScope
60 | ? _lifetimeScope.BeginLifetimeScope(LifetimeScopeTag)
61 | : _lifetimeScope.BeginLifetimeScope());
62 | }
63 | #else
64 | public override JobActivatorScope BeginScope(JobActivatorContext context)
65 | {
66 | if (_scopeConfigurationAction != null)
67 | {
68 | Action configurationAction = builder =>
69 | {
70 | _scopeConfigurationAction(builder, context);
71 | };
72 |
73 | return new AutofacScope(_useTaggedLifetimeScope
74 | ? _lifetimeScope.BeginLifetimeScope(LifetimeScopeTag, configurationAction)
75 | : _lifetimeScope.BeginLifetimeScope(configurationAction));
76 | }
77 |
78 | return new AutofacScope(_useTaggedLifetimeScope
79 | ? _lifetimeScope.BeginLifetimeScope(LifetimeScopeTag)
80 | : _lifetimeScope.BeginLifetimeScope());
81 | }
82 | #endif
83 |
84 | private sealed class AutofacScope : JobActivatorScope
85 | {
86 | private readonly ILifetimeScope _lifetimeScope;
87 |
88 | public AutofacScope(ILifetimeScope lifetimeScope)
89 | {
90 | _lifetimeScope = lifetimeScope;
91 | }
92 |
93 | public override object Resolve(Type type)
94 | {
95 | return _lifetimeScope.Resolve(type);
96 | }
97 |
98 | public override void DisposeScope()
99 | {
100 | _lifetimeScope.Dispose();
101 | }
102 | }
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/src/Hangfire.Autofac/GlobalConfigurationExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Autofac;
3 | using Hangfire.Annotations;
4 |
5 | // ReSharper disable once CheckNamespace
6 | namespace Hangfire
7 | {
8 | public static class GlobalConfigurationExtensions
9 | {
10 | public static IGlobalConfiguration UseAutofacActivator(
11 | [NotNull] this IGlobalConfiguration configuration,
12 | [NotNull] ILifetimeScope lifetimeScope, bool useTaggedLifetimeScope = true)
13 | {
14 | if (configuration == null) throw new ArgumentNullException(nameof(configuration));
15 | if (lifetimeScope == null) throw new ArgumentNullException(nameof(lifetimeScope));
16 |
17 | return configuration.UseActivator(new AutofacJobActivator(lifetimeScope, useTaggedLifetimeScope));
18 | }
19 |
20 | #if !NET45
21 | public static IGlobalConfiguration UseAutofacActivator(
22 | [NotNull] this IGlobalConfiguration configuration,
23 | [NotNull] ILifetimeScope lifetimeScope,
24 | [CanBeNull] Action scopeConfigurationAction,
25 | bool useTaggedLifetimeScope = true)
26 | {
27 | if (configuration == null) throw new ArgumentNullException(nameof(configuration));
28 | if (lifetimeScope == null) throw new ArgumentNullException(nameof(lifetimeScope));
29 |
30 | return configuration.UseActivator(new AutofacJobActivator(lifetimeScope, scopeConfigurationAction, useTaggedLifetimeScope));
31 | }
32 | #endif
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Hangfire.Autofac/Hangfire.Autofac.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net45;netstandard1.3;netstandard2.0
4 | 1591;NU1603
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/Hangfire.Autofac/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | [assembly: AssemblyTitle("Hangfire.Autofac")]
6 | [assembly: AssemblyDescription("Autofac IoC Container integration support for Hangfire.")]
7 | [assembly: Guid("c38d8acf-7b2c-4d7f-84ad-c477879ade3f")]
--------------------------------------------------------------------------------
/src/Hangfire.Autofac/RegistrationExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Autofac.Builder;
4 | using Hangfire.Annotations;
5 |
6 | // ReSharper disable once CheckNamespace
7 | namespace Hangfire
8 | {
9 | ///
10 | /// Adds registration syntax to the type.
11 | ///
12 | public static class RegistrationExtensions
13 | {
14 | private static readonly object[] EmptyObjectArray =
15 | #if NET45
16 | new object[0]
17 | #else
18 | Array.Empty