diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
new file mode 100644
index 0000000..95adf14
--- /dev/null
+++ b/.config/dotnet-tools.json
@@ -0,0 +1,12 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "gitversion.tool": {
+ "version": "5.12.0",
+ "commands": [
+ "dotnet-gitversion"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..a503ea3
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,45 @@
+root = true
+
+# Default settings
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 4
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+# Xml project files
+[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}]
+indent_size = 2
+ij_xml_space_inside_empty_tag = true
+
+# Xml files
+[*.{xml,stylecop,resx,ruleset}]
+indent_size = 2
+ij_xml_space_inside_empty_tag = true
+
+# Xml config files
+[*.{props,targets,config,nuspec,conf}]
+indent_size = 2
+ij_xml_space_inside_empty_tag = true
+
+# YAML config files
+[*.{yml,yaml}]
+indent_size = 2
+
+# Shell scripts
+[*.{sh,ps1}]
+end_of_line = lf
+indent_size = 2
+
+[*.{cmd,bat}]
+end_of_line = crlf
+indent_size = 2
+
+# JSON
+[*.{json,json5,jsonc}]
+indent_size = 2
+
+# CSharp
+[*.cs]
+max_line_length = off
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..ffa977f
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,67 @@
+# Copied from the .NET runtime repository
+# https://github.com/dotnet/runtime/blob/v8.0.0/.gitattributes
+
+# Set default behavior to automatically normalize line endings.
+* text=auto
+
+*.doc diff=astextplain
+*.DOC diff=astextplain
+*.docx diff=astextplain
+*.DOCX diff=astextplain
+*.dot diff=astextplain
+*.DOT diff=astextplain
+*.pdf diff=astextplain
+*.PDF diff=astextplain
+*.rtf diff=astextplain
+*.RTF diff=astextplain
+
+*.jpg binary
+*.png binary
+*.gif binary
+
+*.lss text
+
+# Force bash scripts to always use lf line endings so that if a repo is accessed
+# in Unix via a file share from Windows, the scripts will work.
+*.in text eol=lf
+*.sh text eol=lf
+
+# Likewise, force cmd and batch scripts to always use crlf
+*.cmd text eol=crlf
+*.bat text eol=crlf
+
+*.cs text=auto diff=csharp
+*.vb text=auto
+*.resx text=auto
+*.c text=auto
+*.cpp text=auto
+*.cxx text=auto
+*.h text=auto
+*.hxx text=auto
+*.py text=auto
+*.rb text=auto
+*.java text=auto
+*.html text=auto
+*.htm text=auto
+*.css text=auto
+*.scss text=auto
+*.sass text=auto
+*.less text=auto
+*.js text=auto
+*.lisp text=auto
+*.clj text=auto
+*.sql text=auto
+*.php text=auto
+*.lua text=auto
+*.m text=auto
+*.asm text=auto
+*.erl text=auto
+*.fs text=auto
+*.fsx text=auto
+*.hs text=auto
+
+*.csproj text=auto
+*.vbproj text=auto
+*.fsproj text=auto
+*.dbproj text=auto
+*.sln text=auto eol=crlf
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 0000000..61a323b
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1 @@
+* @gsoft-inc/internal-developer-platform
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000..ed92054
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,32 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Environment (please complete the following information):**
+ - OS: [e.g. Windows]
+ - Version: [e.g. 1.2.3]
+ - IDE: [e.g. Rider]
+ - etc.
+
+**Additional context**
+Add any other context about the problem here.
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000..ec4bb38
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1 @@
+blank_issues_enabled: false
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000..24473de
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,20 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
\ No newline at end of file
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..3ee629a
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,13 @@
+
+
+## Description of changes
+
+
+## Breaking changes
+
+
+## Additional checks
+
+
+- [ ] Updated the documentation of the project to reflect the changes
+- [ ] Added new tests that cover the code changes
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..ede3fa3
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,27 @@
+name: CI
+
+on:
+ pull_request:
+ branches: [main]
+ paths-ignore: ["*.md"]
+
+jobs:
+ main:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - uses: actions/setup-dotnet@v4
+ with:
+ source-url: ${{ secrets.NUGET_GSOFTDEV_FEED_URL }}
+ env:
+ NUGET_AUTH_TOKEN: ${{ secrets.GSOFT_NUGET_API_KEY }}
+
+ - run: ./Build.ps1
+ shell: pwsh
+ env:
+ NUGET_SOURCE: ${{ secrets.NUGET_GSOFTDEV_FEED_URL }}
+ NUGET_API_KEY: ${{ secrets.GSOFT_NUGET_API_KEY }}
diff --git a/.github/workflows/jira.yml b/.github/workflows/jira.yml
new file mode 100644
index 0000000..b3fc5e0
--- /dev/null
+++ b/.github/workflows/jira.yml
@@ -0,0 +1,34 @@
+name: Jira
+
+on:
+ pull_request:
+ branches: [main]
+ paths-ignore: ["*.md"]
+
+jobs:
+ main:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check Jira Story
+ shell: pwsh
+ run: |
+ Install-Module JiraPS -Scope CurrentUser -Force
+ if ("$env:GITHUB_HEAD_REF" -like "*renovate/*" -eq $True)
+ {
+ Write-Host "Skipping, renovate branch detected"
+ return
+ }
+
+ Set-JiraConfigServer -Server "${{ secrets.JIRA_URL }}"
+ if("$env:GITHUB_HEAD_REF" -match "[A-Za-z]+[_-][0-9]+" -eq $False)
+ {
+ throw "Branch name $env:GITHUB_HEAD_REF doesn't respect the required pattern."
+ }
+
+ $JiraIssueKey = $Matches[0]
+ $PWord = ConvertTo-SecureString -String "${{ secrets.JIRA_API_TOKEN }}" -AsPlainText -Force
+ $Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "${{ secrets.JIRA_USERNAME }}", $PWord
+
+ Write-Host "Retrieving Jira issue with number $JiraIssueKey"
+ Get-JiraIssue -Key $JiraIssueKey -Credential $Credential -ErrorAction Stop | out-null
+ Write-Host "Successfully retrieved Jira issue"
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
new file mode 100644
index 0000000..4c6721e
--- /dev/null
+++ b/.github/workflows/publish.yml
@@ -0,0 +1,24 @@
+name: Publish
+
+on:
+ push:
+ branches: [main]
+ tags: ["*.*.*"]
+ paths-ignore: ["*.md"]
+
+jobs:
+ main:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - uses: actions/setup-dotnet@v4
+
+ - run: ./Build.ps1
+ shell: pwsh
+ env:
+ NUGET_SOURCE: ${{ secrets.NUGET_GSOFT_FEED_URL }}
+ NUGET_API_KEY: ${{ secrets.WORKLEAP_NUGET_API_KEY }}
diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml
new file mode 100644
index 0000000..8862bf9
--- /dev/null
+++ b/.github/workflows/semgrep.yml
@@ -0,0 +1,50 @@
+name: Semgrep scan
+
+on:
+ pull_request:
+ branches: ["main", "master"]
+ workflow_dispatch: {}
+ schedule:
+ - cron: "52 2 * * 6"
+
+jobs:
+ semgrep:
+ runs-on: ubuntu-latest
+ permissions:
+ security-events: write
+
+ container:
+ image: returntocorp/semgrep
+
+ steps:
+ - name: Checkout all commits and tags
+ uses: actions/checkout@v4
+ if: ${{ github.event_name == 'pull_request' }}
+ with:
+ fetch-depth: 0
+
+ - name: Checkout single commit
+ uses: actions/checkout@v4
+ if: ${{ github.event_name != 'pull_request' }}
+
+ - name: Pull request scan
+ if: ${{ github.event_name == 'pull_request' }}
+ run: semgrep scan --config=auto --verbose --time --error --baseline-commit ${{ github.event.pull_request.base.sha }}
+
+ - name: Full scan
+ if: ${{ github.event_name != 'pull_request' }}
+ run: semgrep scan --config=auto --verbose --time --sarif --output report.sarif
+
+ - name: Save report as pipeline artifact
+ if: ${{ github.event_name != 'pull_request' }}
+ uses: actions/upload-artifact@v3
+ with:
+ name: report.sarif
+ path: report.sarif
+
+ - name: Publish code scanning alerts
+ if: ${{ github.event_name != 'pull_request' }}
+ uses: github/codeql-action/upload-sarif@v2
+ with:
+ sarif_file: report.sarif
+ category: semgrep
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..fc5035e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,487 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from `dotnet new gitignore`
+
+# dotenv files
+.env
+
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+[Ll]ogs/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# Tye
+.tye/
+
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.tlog
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio 6 auto-generated project file (contains which files were open etc.)
+*.vbp
+
+# Visual Studio 6 workspace and project file (working project files containing files to include in project)
+*.dsw
+*.dsp
+
+# Visual Studio 6 technical files
+*.ncb
+*.aps
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# Visual Studio History (VSHistory) files
+.vshistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd
+
+# VS Code files for those working on multiple tools
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+*.code-workspace
+
+# Local History for Visual Studio Code
+.history/
+
+# Windows Installer files from build outputs
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# JetBrains Rider
+*.sln.iml
+.idea
+
+##
+## Visual studio for Mac
+##
+
+
+# globs
+Makefile.in
+*.userprefs
+*.usertasks
+config.make
+config.status
+aclocal.m4
+install-sh
+autom4te.cache/
+*.tar.gz
+tarballs/
+test-results/
+
+# Mac bundle stuff
+*.dmg
+*.app
+
+# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore
+# Windows thumbnail cache files
+Thumbs.db
+ehthumbs.db
+ehthumbs_vista.db
+
+# Dump file
+*.stackdump
+
+# Folder config file
+[Dd]esktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+
+# Vim temporary swap files
+*.swp
+
+# Build output
+.output/
diff --git a/Build.ps1 b/Build.ps1
new file mode 100644
index 0000000..94a0fa4
--- /dev/null
+++ b/Build.ps1
@@ -0,0 +1,74 @@
+#Requires -Version 5.0
+
+Begin {
+ $ErrorActionPreference = "stop"
+}
+
+Process {
+ function Exec([scriptblock]$Command) {
+ & $Command
+ if ($LASTEXITCODE -ne 0) {
+ throw ("An error occurred while executing command: {0}" -f $Command)
+ }
+ }
+
+ $workingDir = $PSScriptRoot
+ $outputDir = Join-Path $PSScriptRoot ".output"
+ $nupkgsPath = Join-Path $outputDir "*.nupkg"
+
+ $testProjectName = [System.IO.Path]::GetFileNameWithoutExtension([System.IO.Path]::GetRandomFileName())
+ $testProjectDir = Join-Path $outputDir $testProjectName
+ $testProjectPath = Join-Path $testProjectDir "$testProjectName.csproj"
+ $testNugetConfigPath = Join-Path $testProjectDir "nuget.config"
+ $testNugetConfigContents = @"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+"@
+
+ try {
+ Push-Location $workingDir
+ Remove-Item $outputDir -Force -Recurse -ErrorAction SilentlyContinue
+
+ # Install GitVersion which is specified in the .config/dotnet-tools.json
+ # https://learn.microsoft.com/en-us/dotnet/core/tools/local-tools-how-to-use
+ Exec { & dotnet tool restore }
+
+ # Let GitVersion compute the NuGet package version
+ $version = Exec { & dotnet dotnet-gitversion /output json /showvariable SemVer }
+
+ # Pack using NuGet.exe
+ Exec { & nuget pack Workleap.DotNet.CodingStandards.nuspec -OutputDirectory $outputDir -Version $version -ForceEnglishOutput }
+
+ # Create a new test console project, add our newly created package and try to build it in release mode
+ # The default .NET console project template with top-level statements should not trigger any warnings
+ # We treat warnings as errors even though it's supposed to be already enabled by our package,
+ # just in case the package is not working as expected
+ Exec { & dotnet new console --name $testProjectName --output $testProjectDir }
+ Set-Content -Path $testNugetConfigPath -Value $testNugetConfigContents
+ Exec { & dotnet add $testProjectPath package Workleap.DotNet.CodingStandards --version $version }
+ Exec { & dotnet build $testProjectPath --configuration Release /p:TreatWarningsAsErrors=true }
+
+ # Push to a NuGet feed if the environment variables are set
+ if (($null -ne $env:NUGET_SOURCE ) -and ($null -ne $env:NUGET_API_KEY)) {
+ Exec { & dotnet nuget push "$nupkgsPath" -s $env:NUGET_SOURCE -k $env:NUGET_API_KEY }
+ }
+ }
+ finally {
+ Pop-Location
+ }
+}
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..cf0be6f
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,3 @@
+# Contributing
+
+We do not accept external pull requests yet.
\ No newline at end of file
diff --git a/GitVersion.yml b/GitVersion.yml
new file mode 100644
index 0000000..523a586
--- /dev/null
+++ b/GitVersion.yml
@@ -0,0 +1,94 @@
+assembly-versioning-scheme: MajorMinorPatch
+assembly-file-versioning-scheme: MajorMinorPatch
+assembly-informational-format: "{NugetVersion}"
+mode: ContinuousDelivery
+increment: Inherit
+continuous-delivery-fallback-tag: ci
+tag-prefix: "[vV]"
+major-version-bump-message: '\+semver:\s?(breaking|major)'
+minor-version-bump-message: '\+semver:\s?(feature|minor)'
+patch-version-bump-message: '\+semver:\s?(fix|patch)'
+no-bump-message: '\+semver:\s?(none|skip)'
+legacy-semver-padding: 4
+build-metadata-padding: 4
+commits-since-version-source-padding: 4
+tag-pre-release-weight: 60000
+commit-message-incrementing: Enabled
+update-build-number: true
+
+branches:
+ main:
+ regex: ^(master|main)$
+ mode: ContinuousDeployment
+ tag: preview
+ increment: Patch
+ prevent-increment-of-merged-branch-version: true
+ track-merge-target: false
+ source-branches: ["develop", "release"]
+ tracks-release-branches: false
+ is-release-branch: false
+ is-mainline: true
+ pre-release-weight: 55000
+ develop:
+ regex: ^dev(elop)?(ment)?$
+ mode: ContinuousDeployment
+ tag: alpha
+ increment: Minor
+ prevent-increment-of-merged-branch-version: false
+ track-merge-target: true
+ source-branches: []
+ tracks-release-branches: true
+ is-release-branch: false
+ is-mainline: false
+ pre-release-weight: 0
+ release:
+ regex: ^releases?[/-]
+ mode: ContinuousDelivery
+ tag: beta
+ increment: None
+ prevent-increment-of-merged-branch-version: true
+ track-merge-target: false
+ source-branches: ["develop", "main", "support", "release"]
+ tracks-release-branches: false
+ is-release-branch: true
+ is-mainline: false
+ pre-release-weight: 30000
+ feature:
+ regex: ^features?[/-]
+ mode: ContinuousDelivery
+ tag: useBranchName
+ increment: Inherit
+ prevent-increment-of-merged-branch-version: false
+ track-merge-target: false
+ source-branches:
+ ["develop", "main", "release", "feature", "support", "hotfix"]
+ tracks-release-branches: false
+ is-release-branch: false
+ is-mainline: false
+ pre-release-weight: 30000
+ pull-request:
+ regex: ^(pull|pull\-requests|pr)[/-]
+ mode: ContinuousDelivery
+ tag: PullRequest
+ increment: Inherit
+ prevent-increment-of-merged-branch-version: false
+ tag-number-pattern: '[/-](?\d+)[-/]'
+ track-merge-target: false
+ source-branches:
+ ["develop", "main", "release", "feature", "support", "hotfix"]
+ tracks-release-branches: false
+ is-release-branch: false
+ is-mainline: false
+ pre-release-weight: 30000
+ hotfix:
+ regex: ^hotfix(es)?[/-]
+ mode: ContinuousDelivery
+ tag: beta
+ increment: Patch
+ prevent-increment-of-merged-branch-version: false
+ track-merge-target: false
+ source-branches: ["develop", "main", "support"]
+ tracks-release-branches: false
+ is-release-branch: false
+ is-mainline: false
+ pre-release-weight: 30000
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d9a10c0
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,176 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/README.md b/README.md
index 15bc546..74e9584 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,82 @@
-# wl-dotnet-codingstandards
-Workleap recommended coding standards for .NET.
+# Workleap.DotNet.CodingStandards
+
+[![nuget](https://img.shields.io/nuget/v/Workleap.DotNet.CodingStandards.svg?logo=nuget)](https://www.nuget.org/packages/Workleap.DotNet.CodingStandards/)
+[![build](https://img.shields.io/github/actions/workflow/status/gsoft-inc/wl-dotnet-codingstandards/publish.yml?logo=github&branch=main)](https://github.com/gsoft-inc/wl-dotnet-codingstandards/actions/workflows/publish.yml)
+
+This package provides a set of **programming standards for .NET projects**, including rules for **style**, **quality**, **security**, and **performance**. It relies on [built-in .NET analyzers](https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/overview) that are shipped with the .NET SDK.
+
+During development, the package will provide warnings :warning: when standards are not met. For a production build (`Release` configuration), these warnings will be treated as errors :x: and will make the build fail.
+
+## Getting started
+
+Install the NuGet package in your project:
+
+```
+dotnet add package Workleap.DotNet.CodingStandards
+```
+
+If you are using [StyleCop.Analyzers](https://www.nuget.org/packages/StyleCop.Analyzers), you can safely remove it from your project. You can also remove the relevant parts of your `.editorconfig` files which contain analysis rules configuration.
+
+If you also have a `Directory.Build.props` file in your solution, you can remove properties that are [already set by this package](src/buildTransitive/Workleap.DotNet.CodingStandards.props).
+
+## What's included
+
+- Code style and formatting options, including indentation, line wrapping, encoding, new lines preferences, and more.
+- .NET and C# coding conventions, including naming, preferences for types, modifiers, code blocks, expressions, pattern matching, using directives, parentheses, and much more.
+- Project properties, including deterministic build, strict mode, continuous integration build detection, [faster package restoration](https://learn.microsoft.com/en-us/nuget/reference/msbuild-targets#restoring-with-msbuild-static-graph-evaluation), and [faster builds on Visual Studio](https://devblogs.microsoft.com/visualstudio/vs-toolbox-accelerate-your-builds-of-sdk-style-net-projects/), and more.
+- .NET analysis rules configuration, including style rules (`IDExxxx`) and code analysis rules (`CAxxxx`). These rules have been manually configured to provide a good balance between quality, performance, security, and build time.
+- Banned APIs, such as `DateTime.Now` and `DateTimeOffset.Now` (use their UTC counterparts instead).
+
+## What's NOT included
+
+- Enabling a specific or latest C# language version.
+- Enabling nullable reference types by default.
+- Enabling implicit using directives by default.
+- Enforcing a specific target framework.
+- Code styles for files that are not C# source files (e.g. `.csproj`, `.json`, etc.).
+
+We believe that most of these settings should be set on a per-project basis, and decided by the project's maintainers.
+
+For files other than C# source files, it is technically impossible for this package to enforce code styles, so you will have to configure their style using your own `.editorconfig` files.
+
+## How it works
+
+This package comes with a set of `.props` and `.targets` files that are automatically imported into your project when you install the package. These files contain MSBuild properties and targets that configure the build process and the code analysis rules.
+
+It also includes multiple `.editorconfig` files that are automatically imported by Roslyn during the build process.
+
+## Facilitating package adoption
+
+From experience, installing the package will result in numerous warnings, the majority of which are related to code formatting. We recommend addressing these in several steps to minimize the impact on code review, using the [dotnet format](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-format) utility, which is included in the .NET SDK.
+
+Firstly, warnings related to code formatting **can be automatically corrected**. This includes: indentation, unnecessary spaces, empty lines, braces, file-scoped namespaces, unnecessary using directives, etc. Here is the command to execute:
+
+```
+dotnet format --diagnostics IDE0001 IDE0004 IDE0005 IDE0007 IDE0009 IDE0011 IDE0055 IDE0161 IDE2000 IDE2001 IDE2002 IDE2003 IDE2004 IDE2005 IDE2006 --verbosity diagnostic
+```
+
+Once the pull request is merged, one can then attempt to automatically correct the remaining warnings. Without the noise of formatting warnings, it will be easier to focus on them:
+
+```
+dotnet format --severity warn --verbosity diagnostic
+```
+
+You can also modify the command to specify the IDs of the analysis rules you wish to automatically correct (if a fix is available). In this way, you avoid manual work, and breaking the correction into several pull requests will increase developers' confidence in the process of adopting new standards.
+
+All rules included in this package **can be disabled or modified** in an `.editorconfig` file that you can add to your project. You can also **disable a rule for a specific line or block of code** using `#pragma` directives or `[SuppressMessage]` attributes. Learn more about [configuring code analysis rules](https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/suppress-warnings). Remember to always justify why a rule is disabled or modified.
+
+## References
+
+- [Configuration files for code analysis rules: Global analyzer options](https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/configuration-files#global-analyzerconfig) (Microsoft documentation).
+- [Sharing coding style and Roslyn analyzers across projects](https://www.meziantou.net/sharing-coding-style-and-roslyn-analyzers-across-projects.htm) (blog post written by [Gérald Barré](https://github.com/meziantou)).
+- [Microsoft.CodeAnalysis.NetAnalyzers package content](https://nuget.info/packages/Microsoft.CodeAnalysis.NetAnalyzers/8.0.0) (NuGet.info).
+
+## Build and release process
+
+This project uses [GitVersion](https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/overview) as a .NET tool during the build process to automatically compute the version number for preview packages that are automatically published on the main branch and pull requests.
+
+To publish a new public (non-preview) version, simply create a new release on GitHub with a `x.y.z` tag.
+
+## License
+
+Copyright © 2024, Workleap. This code is licensed under the Apache License, Version 2.0. You may obtain a copy of this license at https://github.com/gsoft-inc/gsoft-license/blob/master/LICENSE.
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000..8ca74c5
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,3 @@
+# Security Policy
+
+If you'd like to report a vulnerability, please open a GitHub issue.
diff --git a/Workleap.DotNet.CodingStandards.nuspec b/Workleap.DotNet.CodingStandards.nuspec
new file mode 100644
index 0000000..c428b89
--- /dev/null
+++ b/Workleap.DotNet.CodingStandards.nuspec
@@ -0,0 +1,23 @@
+
+
+
+ Workleap.DotNet.CodingStandards
+ $version$
+ Workleap
+ Workleap
+ true
+ Apache-2.0
+ README.md
+ https://github.com/gsoft-inc/wl-dotnet-codingstandards
+ Workleap recommended coding standards for .NET.
+ Copyright © Workleap
+
+
+
+
+
+
+
+
+
+
diff --git a/global.json b/global.json
new file mode 100644
index 0000000..72500d3
--- /dev/null
+++ b/global.json
@@ -0,0 +1,7 @@
+{
+ "sdk": {
+ "version": "8.0.201",
+ "rollForward": "latestMinor",
+ "allowPrerelease": false
+ }
+}
diff --git a/renovate.json b/renovate.json
new file mode 100644
index 0000000..b6e4fca
--- /dev/null
+++ b/renovate.json
@@ -0,0 +1,52 @@
+{
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
+ "platform": "github",
+ "labels": ["renovate"],
+ "extends": [
+ "config:base",
+ ":rebaseStalePrs"
+ ],
+ "enabledManagers": [
+ "github-actions",
+ "nuget"
+ ],
+ "stabilityDays": 3,
+ "prHourlyLimit": 0,
+ "prConcurrentLimit": 0,
+ "branchConcurrentLimit": 0,
+ "dependencyDashboard": false,
+ "gitAuthor": "Renovate Bot ",
+ "packageRules": [
+ {
+ "matchManagers": ["nuget"],
+ "groupName": "NuGet dependencies"
+ },
+ {
+ "matchPackageNames": ["dotnet-sdk"],
+ "groupName": "Dotnet SDK",
+ "description": "Only update patch and minor for the dotnet SDK version within the global.json",
+ "extends": [":disableMajorUpdates"]
+ },
+ {
+ "matchManagers": ["github-actions"],
+ "groupName": "Pipeline dependencies"
+ }
+ ],
+ "customManagers": [
+ {
+ "description": "nuspec files manager (not built-in in Renovate's nuget manager)",
+ "customType": "regex",
+ "fileMatch": ["\\.nuspec$"],
+ "matchStringsStrategy": "any",
+ "matchStrings": [
+ ".*?)\"\\s+version=\"(?.*?)\"\\s*\\/>"
+ ],
+ "datasourceTemplate": "nuget",
+ "versioningTemplate": "nuget"
+ }
+ ],
+ "vulnerabilityAlerts": {
+ "enabled": true,
+ "labels": ["security"]
+ }
+}
diff --git a/src/buildTransitive/Workleap.DotNet.CodingStandards.props b/src/buildTransitive/Workleap.DotNet.CodingStandards.props
new file mode 100644
index 0000000..a144399
--- /dev/null
+++ b/src/buildTransitive/Workleap.DotNet.CodingStandards.props
@@ -0,0 +1,29 @@
+
+
+ true
+ strict
+ true
+ true
+ latest-all
+ true
+
+
+ true
+
+
+ true
+ true
+ true
+ true
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
diff --git a/src/buildTransitive/Workleap.DotNet.CodingStandards.targets b/src/buildTransitive/Workleap.DotNet.CodingStandards.targets
new file mode 100644
index 0000000..583b67e
--- /dev/null
+++ b/src/buildTransitive/Workleap.DotNet.CodingStandards.targets
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
diff --git a/src/files/1_FileDefaults.editorconfig b/src/files/1_FileDefaults.editorconfig
new file mode 100644
index 0000000..84de19c
--- /dev/null
+++ b/src/files/1_FileDefaults.editorconfig
@@ -0,0 +1,10 @@
+is_global = true
+global_level = -1
+
+# Default settings for C# and Visual Basic
+charset = utf-8
+indent_style = space
+indent_size = 4
+insert_final_newline = false
+trim_trailing_whitespace = true
+max_line_length = off
diff --git a/src/files/2_CodeStyle.editorconfig b/src/files/2_CodeStyle.editorconfig
new file mode 100644
index 0000000..0a20432
--- /dev/null
+++ b/src/files/2_CodeStyle.editorconfig
@@ -0,0 +1,264 @@
+is_global = true
+global_level = -1
+
+#### BEGIN GENERATED CONTENT FROM VISUAL STUDIO CODE STYLE EDITOR ####
+
+# These options were hand-picked in VS Options > Text Editor > C# > Code Style
+# then exported to .editorconfig using the "Generate .editorconfig file from settings" feature
+
+#### .NET Coding Conventions ####
+
+# Organize usings
+dotnet_separate_import_directive_groups = false
+dotnet_sort_system_directives_first = true
+file_header_template = unset
+
+# this. and Me. preferences
+dotnet_style_qualification_for_event = true:warning
+dotnet_style_qualification_for_field = true:warning
+dotnet_style_qualification_for_method = true:warning
+dotnet_style_qualification_for_property = true:warning
+
+# Language keywords vs BCL types preferences
+dotnet_style_predefined_type_for_locals_parameters_members = true:warning
+dotnet_style_predefined_type_for_member_access = true:warning
+
+# Parentheses preferences
+dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
+dotnet_style_parentheses_in_other_binary_operators = always_for_clarity
+dotnet_style_parentheses_in_other_operators = never_if_unnecessary
+dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity
+
+# Modifier preferences
+dotnet_style_require_accessibility_modifiers = for_non_interface_members
+
+# Expression-level preferences
+dotnet_style_coalesce_expression = true
+dotnet_style_collection_initializer = true
+dotnet_style_explicit_tuple_names = true
+dotnet_style_namespace_match_folder = true
+dotnet_style_null_propagation = true
+dotnet_style_object_initializer = true
+dotnet_style_operator_placement_when_wrapping = beginning_of_line
+dotnet_style_prefer_auto_properties = true:suggestion
+dotnet_style_prefer_collection_expression = true
+dotnet_style_prefer_compound_assignment = true
+dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
+dotnet_style_prefer_conditional_expression_over_return = true
+dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed
+dotnet_style_prefer_inferred_anonymous_type_member_names = true
+dotnet_style_prefer_inferred_tuple_names = true
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true
+dotnet_style_prefer_simplified_boolean_expressions = true
+dotnet_style_prefer_simplified_interpolation = true
+
+# Field preferences
+dotnet_style_readonly_field = true:warning
+
+# Parameter preferences
+dotnet_code_quality_unused_parameters = all
+
+# Suppression preferences
+dotnet_remove_unnecessary_suppression_exclusions = none
+
+# New line preferences
+dotnet_style_allow_multiple_blank_lines_experimental = false:warning
+dotnet_style_allow_statement_immediately_after_block_experimental = false:warning
+
+#### C# Coding Conventions ####
+
+# var preferences
+csharp_style_var_elsewhere = true:warning
+csharp_style_var_for_built_in_types = true:warning
+csharp_style_var_when_type_is_apparent = true:warning
+
+# Expression-bodied members
+csharp_style_expression_bodied_accessors = true:suggestion
+csharp_style_expression_bodied_constructors = false
+csharp_style_expression_bodied_indexers = true:suggestion
+csharp_style_expression_bodied_lambdas = true
+csharp_style_expression_bodied_local_functions = false
+csharp_style_expression_bodied_methods = false
+csharp_style_expression_bodied_operators = false
+csharp_style_expression_bodied_properties = true
+
+# Pattern matching preferences
+csharp_style_pattern_matching_over_as_with_null_check = true
+csharp_style_pattern_matching_over_is_with_cast_check = true
+csharp_style_prefer_extended_property_pattern = true
+csharp_style_prefer_not_pattern = true
+csharp_style_prefer_pattern_matching = true:suggestion
+csharp_style_prefer_switch_expression = true
+
+# Null-checking preferences
+csharp_style_conditional_delegate_call = true
+
+# Modifier preferences
+csharp_prefer_static_local_function = true
+csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async
+csharp_style_prefer_readonly_struct = true
+csharp_style_prefer_readonly_struct_member = true
+
+# Code-block preferences
+csharp_prefer_braces = true:warning
+csharp_prefer_simple_using_statement = true:silent
+csharp_style_namespace_declarations = file_scoped:warning
+csharp_style_prefer_method_group_conversion = true:suggestion
+csharp_style_prefer_primary_constructors = true
+csharp_style_prefer_top_level_statements = true
+
+# Expression-level preferences
+csharp_prefer_simple_default_expression = true
+csharp_style_deconstructed_variable_declaration = true
+csharp_style_implicit_object_creation_when_type_is_apparent = true
+csharp_style_inlined_variable_declaration = true
+csharp_style_prefer_index_operator = true
+csharp_style_prefer_local_over_anonymous_function = true
+csharp_style_prefer_null_check_over_type_check = true
+csharp_style_prefer_range_operator = true
+csharp_style_prefer_tuple_swap = true
+csharp_style_prefer_utf8_string_literals = true
+csharp_style_throw_expression = true
+csharp_style_unused_value_assignment_preference = discard_variable
+csharp_style_unused_value_expression_statement_preference = discard_variable:warning
+
+# 'using' directive preferences
+csharp_using_directive_placement = outside_namespace:warning
+
+# New line preferences
+csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = false:warning
+csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = false:suggestion
+csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = false:warning
+csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false:warning
+csharp_style_allow_embedded_statements_on_same_line_experimental = false:warning
+
+#### C# Formatting Rules ####
+
+# New line preferences
+csharp_new_line_before_catch = true
+csharp_new_line_before_else = true
+csharp_new_line_before_finally = true
+csharp_new_line_before_members_in_anonymous_types = true
+csharp_new_line_before_members_in_object_initializers = true
+csharp_new_line_before_open_brace = all
+csharp_new_line_between_query_expression_clauses = true
+
+# Indentation preferences
+csharp_indent_block_contents = true
+csharp_indent_braces = false
+csharp_indent_case_contents = true
+csharp_indent_case_contents_when_block = true
+csharp_indent_labels = one_less_than_current
+csharp_indent_switch_labels = true
+
+# Space preferences
+csharp_space_after_cast = false
+csharp_space_after_colon_in_inheritance_clause = true
+csharp_space_after_comma = true
+csharp_space_after_dot = false
+csharp_space_after_keywords_in_control_flow_statements = true
+csharp_space_after_semicolon_in_for_statement = true
+csharp_space_around_binary_operators = before_and_after
+csharp_space_around_declaration_statements = false
+csharp_space_before_colon_in_inheritance_clause = true
+csharp_space_before_comma = false
+csharp_space_before_dot = false
+csharp_space_before_open_square_brackets = false
+csharp_space_before_semicolon_in_for_statement = false
+csharp_space_between_empty_square_brackets = false
+csharp_space_between_method_call_empty_parameter_list_parentheses = false
+csharp_space_between_method_call_name_and_opening_parenthesis = false
+csharp_space_between_method_call_parameter_list_parentheses = false
+csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
+csharp_space_between_method_declaration_name_and_open_parenthesis = false
+csharp_space_between_method_declaration_parameter_list_parentheses = false
+csharp_space_between_parentheses = false
+csharp_space_between_square_brackets = false
+
+# Wrapping preferences
+csharp_preserve_single_line_blocks = true
+csharp_preserve_single_line_statements = false
+
+#### Naming styles ####
+
+# Naming rules
+
+dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
+dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
+dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
+
+dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.types_should_be_pascal_case.symbols = types
+dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
+dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.private_fields_should_be_camel_case_underscore_prefix.severity = suggestion
+dotnet_naming_rule.private_fields_should_be_camel_case_underscore_prefix.symbols = private_fields
+dotnet_naming_rule.private_fields_should_be_camel_case_underscore_prefix.style = camel_case_underscore_prefix
+
+dotnet_naming_rule.static_readonly_fields_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.static_readonly_fields_should_be_pascal_case.symbols = static_readonly_fields
+dotnet_naming_rule.static_readonly_fields_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
+dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.local_variables_should_be_camel_case.severity = suggestion
+dotnet_naming_rule.local_variables_should_be_camel_case.symbols = local_variables
+dotnet_naming_rule.local_variables_should_be_camel_case.style = camel_case
+
+# Symbol specifications
+
+dotnet_naming_symbols.interface.applicable_kinds = interface
+dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.interface.required_modifiers =
+
+dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
+dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.types.required_modifiers =
+
+dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
+dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.non_field_members.required_modifiers =
+
+dotnet_naming_symbols.private_fields.applicable_kinds = field
+dotnet_naming_symbols.private_fields.applicable_accessibilities = private, private_protected
+dotnet_naming_symbols.private_fields.required_modifiers =
+
+dotnet_naming_symbols.static_readonly_fields.applicable_kinds = field
+dotnet_naming_symbols.static_readonly_fields.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.static_readonly_fields.required_modifiers = static, readonly
+
+dotnet_naming_symbols.constant_fields.applicable_kinds = field
+dotnet_naming_symbols.constant_fields.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.constant_fields.required_modifiers = const
+
+dotnet_naming_symbols.local_variables.applicable_kinds = parameter, local
+dotnet_naming_symbols.local_variables.applicable_accessibilities = local
+dotnet_naming_symbols.local_variables.required_modifiers =
+
+# Naming styles
+
+dotnet_naming_style.pascal_case.required_prefix =
+dotnet_naming_style.pascal_case.required_suffix =
+dotnet_naming_style.pascal_case.word_separator =
+dotnet_naming_style.pascal_case.capitalization = pascal_case
+
+dotnet_naming_style.camel_case.required_prefix =
+dotnet_naming_style.camel_case.required_suffix =
+dotnet_naming_style.camel_case.word_separator =
+dotnet_naming_style.camel_case.capitalization = camel_case
+
+dotnet_naming_style.begins_with_i.required_prefix = I
+dotnet_naming_style.begins_with_i.required_suffix =
+dotnet_naming_style.begins_with_i.word_separator =
+dotnet_naming_style.begins_with_i.capitalization = pascal_case
+
+dotnet_naming_style.camel_case_underscore_prefix.required_prefix = _
+dotnet_naming_style.camel_case_underscore_prefix.required_suffix =
+dotnet_naming_style.camel_case_underscore_prefix.word_separator =
+dotnet_naming_style.camel_case_underscore_prefix.capitalization = camel_case
diff --git a/src/files/3_AllProjectsAnalyzers.editorconfig b/src/files/3_AllProjectsAnalyzers.editorconfig
new file mode 100644
index 0000000..570c222
--- /dev/null
+++ b/src/files/3_AllProjectsAnalyzers.editorconfig
@@ -0,0 +1,542 @@
+# global_level must be higher than the NET Analyzer files
+is_global = true
+global_level = 0
+
+#### IDE rules (IDE####) ####
+
+# IDE0001: Simplify name (specifying a full type name is sometimes unnecessary)
+dotnet_diagnostic.IDE0001.severity = warning
+
+# IDE0002: Simplify member access (specifying a type name in a static invocation is sometimes unnecessary)
+dotnet_diagnostic.IDE0002.severity = suggestion
+
+# IDE0003: Remove this or Me qualification (enforce the use of 'this.')
+dotnet_diagnostic.IDE0003.severity = none
+
+# IDE0004: Remove Unnecessary Cast
+dotnet_diagnostic.IDE0004.severity = warning
+
+# IDE0005: Remove unnecessary using directives
+dotnet_diagnostic.IDE0005.severity = warning
+
+# IDE0007: Use implicit type (var)
+dotnet_diagnostic.IDE0007.severity = warning
+
+# IDE0008: Use explicit type (prefer using var)
+dotnet_diagnostic.IDE0008.severity = none
+
+# IDE0009: Add this or Me qualification (enforce the use of 'this.')
+dotnet_diagnostic.IDE0009.severity = warning
+
+# IDE0010: Add missing cases
+dotnet_diagnostic.IDE0010.severity = suggestion
+
+# IDE0011: Add braces
+dotnet_diagnostic.IDE0011.severity = warning
+
+# IDE0016: Use 'throw' expression
+dotnet_diagnostic.IDE0016.severity = none
+
+# IDE0017: Simplify object initialization
+dotnet_diagnostic.IDE0017.severity = suggestion
+
+# IDE0018: Inline variable declaration
+dotnet_diagnostic.IDE0018.severity = suggestion
+
+# IDE0019: Use pattern matching to avoid as followed by a null check
+dotnet_diagnostic.IDE0019.severity = suggestion
+
+# IDE0020: Use pattern matching to avoid is check followed by a cast (with variable)
+dotnet_diagnostic.IDE0020.severity = warning
+
+# IDE0021: Use expression body for constructors
+dotnet_diagnostic.IDE0021.severity = none
+
+# IDE0022: Use expression body for methods
+dotnet_diagnostic.IDE0022.severity = none
+
+# IDE0023: Use expression body for operators
+dotnet_diagnostic.IDE0023.severity = none
+
+# IDE0024: Use expression body for operators
+dotnet_diagnostic.IDE0024.severity = none
+
+# IDE0025: Use expression body for properties
+dotnet_diagnostic.IDE0025.severity = none
+
+# IDE0026: Use expression body for indexers
+dotnet_diagnostic.IDE0026.severity = none
+
+# IDE0027: Use expression body for accessors
+dotnet_diagnostic.IDE0027.severity = none
+
+# IDE0028: Simplify collection initialization
+dotnet_diagnostic.IDE0028.severity = suggestion
+
+# IDE0029: Use coalesce expression
+dotnet_diagnostic.IDE0029.severity = warning
+
+# IDE0030: Use coalesce expression
+dotnet_diagnostic.IDE0030.severity = warning
+
+# IDE0031: Use null propagation
+dotnet_diagnostic.IDE0031.severity = warning
+
+# IDE0032: Use auto property
+dotnet_diagnostic.IDE0032.severity = none
+
+# IDE0033: Use explicitly provided tuple name
+dotnet_diagnostic.IDE0033.severity = suggestion
+
+# IDE0034: Simplify 'default' expression
+dotnet_diagnostic.IDE0034.severity = suggestion
+
+# IDE0035: Remove unreachable code
+dotnet_diagnostic.IDE0035.severity = none
+
+# IDE0036: Order modifiers
+dotnet_diagnostic.IDE0036.severity = warning
+
+# IDE0037: Use inferred member name
+dotnet_diagnostic.IDE0037.severity = none
+
+# IDE0038: Use pattern matching to avoid is check followed by a cast (without variable)
+dotnet_diagnostic.IDE0038.severity = suggestion
+
+# IDE0039: Use local function
+dotnet_diagnostic.IDE0039.severity = suggestion
+
+# IDE0040: Add accessibility modifiers
+dotnet_diagnostic.IDE0040.severity = warning
+
+# IDE0041: Use 'is null' check
+dotnet_diagnostic.IDE0041.severity = none
+
+# IDE0042: Deconstruct variable declaration
+dotnet_diagnostic.IDE0042.severity = none
+
+# IDE0043: Invalid format string
+dotnet_diagnostic.IDE0043.severity = warning
+
+# IDE0044: Add readonly modifier
+dotnet_diagnostic.IDE0044.severity = warning
+
+# IDE0045: Use conditional expression for assignment
+dotnet_diagnostic.IDE0045.severity = suggestion
+
+# IDE0046: Use conditional expression for return
+dotnet_diagnostic.IDE0046.severity = suggestion
+
+# IDE0047: Remove unnecessary parentheses
+dotnet_diagnostic.IDE0047.severity = none
+
+# IDE0048: Add parentheses for clarity
+dotnet_diagnostic.IDE0048.severity = none
+
+# IDE0049: Use language keywords instead of framework type names for type references
+dotnet_diagnostic.IDE0049.severity = warning
+
+# IDE0051: Remove unused private members
+dotnet_diagnostic.IDE0051.severity = suggestion
+
+# IDE0052: Remove unread private members
+dotnet_diagnostic.IDE0052.severity = suggestion
+
+# IDE0053: Use expression body for lambdas
+dotnet_diagnostic.IDE0053.severity = none
+
+# IDE0054: Use compound assignment
+dotnet_diagnostic.IDE0054.severity = warning
+
+# IDE0055: Fix formatting (whitespaces, newlines, indentation, spacing, wrapping, etc.)
+dotnet_diagnostic.IDE0055.severity = warning
+
+# IDE0056: Use index operator
+dotnet_diagnostic.IDE0056.severity = suggestion
+
+# IDE0057: Use range operator
+dotnet_diagnostic.IDE0057.severity = suggestion
+
+# IDE0058: Expression value is never used
+dotnet_diagnostic.IDE0058.severity = none
+
+# IDE0059: Unnecessary assignment of a value
+dotnet_diagnostic.IDE0059.severity = warning
+
+# IDE0060: Remove unused parameter
+dotnet_diagnostic.IDE0060.severity = suggestion
+
+# IDE0061: Use expression body for local functions
+dotnet_diagnostic.IDE0061.severity = none
+
+# IDE0062: Make local function 'static'
+dotnet_diagnostic.IDE0062.severity = warning
+
+# IDE0063: Use simple 'using' statement
+dotnet_diagnostic.IDE0063.severity = none
+
+# IDE0064: Make readonly fields writable
+dotnet_diagnostic.IDE0064.severity = none
+
+# IDE0065: Misplaced using directive
+dotnet_diagnostic.IDE0065.severity = warning
+
+# IDE0066: Convert switch statement to expression
+dotnet_diagnostic.IDE0066.severity = suggestion
+
+# IDE0070: Use 'System.HashCode'
+dotnet_diagnostic.IDE0070.severity = suggestion
+
+# IDE0071: Simplify interpolation
+dotnet_diagnostic.IDE0071.severity = warning
+
+# IDE0072: Add missing cases
+dotnet_diagnostic.IDE0072.severity = none
+
+# IDE0073: The file header is missing or not located at the top of the file
+dotnet_diagnostic.IDE0073.severity = none
+
+# IDE0074: Use compound assignment
+dotnet_diagnostic.IDE0074.severity = warning
+
+# IDE0075: Simplify conditional expression
+dotnet_diagnostic.IDE0075.severity = none
+
+# IDE0076: Invalid global 'SuppressMessageAttribute'
+dotnet_diagnostic.IDE0076.severity = warning
+
+# IDE0077: Avoid legacy format target in 'SuppressMessageAttribute'
+dotnet_diagnostic.IDE0077.severity = none
+
+# IDE0078: Use pattern matching
+dotnet_diagnostic.IDE0078.severity = suggestion
+
+# IDE0079: Remove unnecessary suppression
+dotnet_diagnostic.IDE0079.severity = suggestion
+
+# IDE0080: Remove unnecessary suppression operator
+dotnet_diagnostic.IDE0080.severity = warning
+
+# IDE0081: Remove unnecessary suppression operator
+dotnet_diagnostic.IDE0081.severity = none
+
+# IDE0082: 'typeof' can be converted to 'nameof'
+dotnet_diagnostic.IDE0082.severity = warning
+
+# IDE0083: Use pattern matching
+dotnet_diagnostic.IDE0083.severity = suggestion
+
+# IDE0084: Use pattern matching (IsNot operator)
+dotnet_diagnostic.IDE0084.severity = suggestion
+
+# IDE0090: Use 'new(...)'
+dotnet_diagnostic.IDE0090.severity = none
+
+# IDE0100: Remove redundant equality
+dotnet_diagnostic.IDE0100.severity = warning
+
+# IDE0110: Remove unnecessary discard
+dotnet_diagnostic.IDE0110.severity = warning
+
+# IDE0120: Simplify LINQ expression
+dotnet_diagnostic.IDE0120.severity = none
+
+# IDE0130: Namespace does not match folder structure
+dotnet_diagnostic.IDE0130.severity = warning
+
+# IDE0140: Simplify object creation
+dotnet_diagnostic.IDE0140.severity = none
+
+# IDE0150: Prefer 'null' check over type check
+dotnet_diagnostic.IDE0150.severity = none
+
+# IDE0160: Convert to block scoped namespace
+dotnet_diagnostic.IDE0160.severity = none
+
+# IDE0161: Convert to file-scoped namespace
+dotnet_diagnostic.IDE0161.severity = warning
+
+# IDE0170: Simplify property pattern
+dotnet_diagnostic.IDE0170.severity = warning
+
+# IDE0180: Use tuple swap
+dotnet_diagnostic.IDE0180.severity = suggestion
+
+# IDE0200: Remove unnecessary lambda expression
+dotnet_diagnostic.IDE0200.severity = warning
+
+# IDE0210: Use top-level statements
+dotnet_diagnostic.IDE0210.severity = none
+
+# IDE0211: Use program main
+dotnet_diagnostic.IDE0211.severity = none
+
+# IDE0220: foreach cast
+dotnet_diagnostic.IDE0220.severity = none
+
+# IDE0230: Use UTF8 string literal
+dotnet_diagnostic.IDE0230.severity = suggestion
+
+# IDE0240: Remove redundant nullable directive
+dotnet_diagnostic.IDE0240.severity = suggestion
+
+# IDE0241: Remove unnecessary nullable directive
+dotnet_diagnostic.IDE0241.severity = suggestion
+
+# IDE0250: Make struct readonly
+dotnet_diagnostic.IDE0250.severity = suggestion
+
+# IDE0260: Use pattern matching
+dotnet_diagnostic.IDE0260.severity = suggestion
+
+# IDE0270: Use coalesce expression
+dotnet_diagnostic.IDE0270.severity = suggestion
+
+# IDE0280: Use 'nameof'
+dotnet_diagnostic.IDE0280.severity = warning
+
+# IDE0300 - IDE0305: Use collection expression for:
+dotnet_diagnostic.IDE0300.severity = suggestion # arrays
+dotnet_diagnostic.IDE0301.severity = suggestion # empty
+dotnet_diagnostic.IDE0302.severity = suggestion # stackalloc
+dotnet_diagnostic.IDE0303.severity = suggestion # 'Create' methods
+dotnet_diagnostic.IDE0304.severity = suggestion # Collection builder methods
+dotnet_diagnostic.IDE0305.severity = suggestion # Fluent collection methods (Add, ToList, etc.)
+
+# IDE1005: Delegate invocation can be simplified.
+dotnet_diagnostic.IDE1005.severity = warning
+
+# IDE1006: Naming styles
+dotnet_diagnostic.IDE1006.severity = warning
+
+# IDE2000: Allow multiple blank lines
+dotnet_diagnostic.IDE2000.severity = warning
+
+# IDE2001: Embedded statements must be on their own line
+dotnet_diagnostic.IDE2001.severity = warning
+
+# IDE2002: Consecutive braces must not have blank line between them
+dotnet_diagnostic.IDE2002.severity = warning
+
+# IDE2003: Allow statement immediately after block
+dotnet_diagnostic.IDE2003.severity = warning
+
+# IDE2004: Blank line not allowed after constructor initializer colon
+dotnet_diagnostic.IDE2004.severity = warning
+
+# IDE2004: Blank line not allowed after token in conditional expression
+dotnet_diagnostic.IDE2005.severity = warning
+
+# IDE2004: Blank line not allowed after after token in arrow expression
+dotnet_diagnostic.IDE2006.severity = warning
+
+#### Code Analysis rules (CA####) ####
+
+# CA1002: Do not expose generic lists (List)
+dotnet_diagnostic.CA1002.severity = none
+
+# CA1014: Mark assemblies with CLSCompliantAttribute
+# Disabled because the types of this project aren't exposed to other programming languages
+dotnet_diagnostic.CA1014.severity = none
+
+# CA1024: Use properties where appropriate
+dotnet_diagnostic.CA1024.severity = none
+
+# CA1031: Do not catch general exception types
+dotnet_diagnostic.CA1031.severity = none
+
+# CA1032: Implement standard exception constructors
+dotnet_diagnostic.CA1032.severity = none
+
+# CA1034: Nested types should not be visible
+# Disabled, because convenient for nested option classes, DTOs in controllers, etc.
+dotnet_diagnostic.CA1034.severity = none
+
+# CA1040: Avoid empty interfaces
+# Disabled to allow marker interfaces
+dotnet_diagnostic.CA1040.severity = none
+
+# CA1054: URI parameters should not be strings
+# Disabled because it's simply annoying and the .NET runtime contains method that accept URI strings
+dotnet_diagnostic.CA1054.severity = none
+
+# CA1055: URI return values should not be strings
+# Disabled for convenience and ease of adoption, returning URI strings can also be useful
+dotnet_diagnostic.CA1055.severity = none
+
+# CA1056: URI properties should not be strings
+# Disabled because it's sometimes inconvenient to force properties to use Uri instead of strings
+dotnet_diagnostic.CA1056.severity = none
+
+# CA1062: Validate arguments of public methods
+# Disabled because there's no need to always enforce null-checks thanks to nullable reference types
+dotnet_diagnostic.CA1062.severity = none
+
+# CA1064: Exceptions should be public
+# Disabled, because it's not always relevant in the context of an internal application
+dotnet_diagnostic.CA1064.severity = none
+
+# CA1068: CancellationToken parameters must come last
+dotnet_diagnostic.CA1068.severity = warning
+
+# CA1200: Avoid using cref tags with a prefix
+# Disabled because using 'T:' prefix is actually convenient VS importing the namespace of the referenced type
+dotnet_diagnostic.CA1200.severity = none
+
+# Globalization, culture and case sensitivity rules
+# CA1303: Do not pass literals as localized parameters (disabled, using *.resx files for user-displayed messages might be too much)
+# CA1304: Specify CultureInfo (ex: string.ToLower)
+# CA1305: Specify IFormatProvider (ex: string.Format)
+# CA1307: Specify StringComparison for clarity (ex: string.IndexOf)
+# CA1308: Normalize strings to uppercase (disabled, too strict)
+# CA1309: Use ordinal StringComparison (ex: string.Compare)
+# CA1310: Specify StringComparison for correctness (ex: string.Compare)
+# CA1311: Specify a culture or use an invariant version (ex: string.ToUpper)
+dotnet_diagnostic.CA1303.severity = none
+dotnet_diagnostic.CA1304.severity = suggestion
+dotnet_diagnostic.CA1305.severity = suggestion
+dotnet_diagnostic.CA1307.severity = suggestion
+dotnet_diagnostic.CA1308.severity = none
+dotnet_diagnostic.CA1309.severity = suggestion
+dotnet_diagnostic.CA1310.severity = suggestion
+dotnet_diagnostic.CA1311.severity = suggestion
+
+# CA1507: Use nameof in place of string
+# Disabled because it was suggested when using [Newtonsoft.Json.JsonProperty],
+# which could lead to JSON breaking changes in case of refactoring or obfuscation
+dotnet_diagnostic.CA1507.severity = none
+
+# CA1508: Avoid dead conditional code
+# Disabled because provides false positives in cases with double checked locking and has performance impact
+dotnet_diagnostic.CA1508.severity = none
+
+# CA1510: Use ArgumentNullException throw helper (ArgumentNullException.ThrowIfNull)
+dotnet_diagnostic.CA1510.severity = suggestion
+
+# CA1707: Identifiers should not contain underscores
+# Disabled because this is a common practice in test method names (and other cases)
+dotnet_diagnostic.CA1707.severity = none
+
+# CA1710: Identifiers should have correct suffix
+# Disabled because it's simply annoying (streams types must end with 'Stream', same for queue, stack, collection, dictionary, etc.)
+dotnet_diagnostic.CA1710.severity = none
+
+# CA1711: Identifiers should not have incorrect suffix
+# Disabled because it's sometimes OK to name something ending with Collection even if it doesn't implement ICollection
+dotnet_diagnostic.CA1711.severity = none
+
+# CA1716: Identifiers should not match keywords
+# Some method names such as "Get" or "Set" should be allowed. This rule exists mostly because of VB.NET. As we don't use it, this is fine to disable the rule.
+dotnet_diagnostic.CA1716.severity = none
+
+# CA1720: Identifiers should not contain type names
+dotnet_diagnostic.CA1720.severity = none
+
+# CA1724: Type names should not match namespaces
+# Disabled to increase the adoption of this library, as many projects have classes with the same name of the namespace
+dotnet_diagnostic.CA1724.severity = none
+
+# CA1805: Do not initialize unnecessarily
+dotnet_diagnostic.CA1805.severity = warning
+
+# CA1812: Allow unreferenced code to exist
+dotnet_diagnostic.CA1812.severity = none
+
+# CA1819: Allow properties to return arrays
+dotnet_diagnostic.CA1819.severity = none
+
+# CA1822: Mark members as static
+# Disabled because the compiler might not always be aware of how a member is used
+dotnet_diagnostic.CA1822.severity = none
+
+# CA1848: Use the LoggerMessage delegates
+# Disabled because high-performance logging is overkill in most cases (except in libs with hot paths)
+dotnet_diagnostic.CA1848.severity = none
+
+# CA1859: Use concrete types when possible for improved performance
+# Disabled, down-casting doesn't degrade performance that much
+dotnet_diagnostic.CA1859.severity = none
+
+# CA1863: Use 'CompositeFormat'
+# Disabled, this is fairly new and the performance gains over string.Format isn't worth it
+dotnet_diagnostic.CA1863.severity = none
+
+# CA2000: Dispose objects before losing scope
+# Disabled because disposables don't always need to be disposed in the current scope (ex: HttpClients provided by IHttpClientFactory)
+dotnet_diagnostic.CA2000.severity = none
+
+# CA2007: Do not directly await a Task
+# Disabled because using ConfigureAwait(true) isn't necessary in ASP.NET Core (MVC & APIs) as there is no synchronization context
+dotnet_diagnostic.CA2007.severity = none
+
+# CA2008: Do not create tasks without passing a TaskScheduler
+# Disabled because it's OK to use the default scheduler in most applications (for desktop ones, this might be different)
+dotnet_diagnostic.CA2008.severity = none
+
+# CA2201: Do not raise a generic exception or reserved exception type
+dotnet_diagnostic.CA2201.severity = suggestion
+
+# CA2225: Operator overloads have named alternates
+dotnet_diagnostic.CA2225.severity = none
+
+# CA2227: Collection properties should be read only
+# Disabled to allow collections to have setters (ex: JSON serialization)
+dotnet_diagnostic.CA2227.severity = none
+
+# CA2229: Implement serialization constructors
+# Disabled to not enforce the creation of exception constructors accepting a SerializationInfo and StreamingContext. BinarySerializer is now obsolete and will be removed from .NET 9.
+dotnet_diagnostic.CA2229.severity = none
+
+# CA2234: Pass System.Uri objects instead of strings
+# Disabled, it's more convenient to pass strings in some cases
+dotnet_diagnostic.CA2234.severity = none
+
+# CA2329: Do not deserialize with JsonSerializer using an insecure configuration
+dotnet_diagnostic.CA2329.severity = warning
+
+# CA2330: Ensure that JsonSerializer has a secure configuration when deserializing
+dotnet_diagnostic.CA2330.severity = warning
+
+# Various security rules that are highly unlikely to be necessary when using a proper SAST tool
+# Most of them are concerning the use of non-validated user input in various contexts
+# These rules are also EXTREMELY expensive to execute on a medium-sized codebase (more than 70% of the total time spent on the analysis)
+# Enable them on a case by case basis if you have a specific need for them
+# Additional note: CA3004 and 3007 seemed relevant for web apps but didn't seem to work with basic ASP.NET Core setup
+dotnet_diagnostic.CA3001.severity = none # CA3001: Review code for SQL injection vulnerabilities
+dotnet_diagnostic.CA3002.severity = none # CA3002: Review code for XSS vulnerabilities
+dotnet_diagnostic.CA3003.severity = none # CA3003: Review code for file path injection vulnerabilities
+dotnet_diagnostic.CA3004.severity = none # CA3004: Review code for information disclosure vulnerabilities
+dotnet_diagnostic.CA3005.severity = none # CA3005: Review code for LDAP injection vulnerabilities
+dotnet_diagnostic.CA3006.severity = none # CA3006: Review code for process command injection vulnerabilities
+dotnet_diagnostic.CA3007.severity = none # CA3007: Review code for open redirect vulnerabilities
+dotnet_diagnostic.CA3008.severity = none # CA3008: Review code for XPath injection vulnerabilities
+dotnet_diagnostic.CA3009.severity = none # CA3009: Review code for XML injection vulnerabilities
+dotnet_diagnostic.CA3010.severity = none # CA3010: Review code for XAML injection vulnerabilities
+dotnet_diagnostic.CA3011.severity = none # CA3011: Review code for DLL injection vulnerabilities
+dotnet_diagnostic.CA3012.severity = none # CA3012: Review code for regex injection vulnerabilities
+
+# CA5362: Potential reference cycle in deserialized object graph
+# Disabled because the use of SerializableAttribute on our types is almost non-existent
+dotnet_diagnostic.CA5362.severity = none
+
+# CA3076: Insecure XSLT Script Execution
+dotnet_diagnostic.CA3076.severity = none
+
+# CA5389: Do not add archive item's path to the target file system path
+# Disabled because this rule is very expensive and using ZipArchive is not that common
+dotnet_diagnostic.CA5389.severity = none
+
+# CA5394: Do not use insecure randomness
+# Disabled because it's OK to use Random in non security-critical contexts
+dotnet_diagnostic.CA5394.severity = none
+
+# CA5399: Enable HttpClient certificate revocation list check
+# CA5400: Ensure HttpClient certificate revocation list check is not disabled
+dotnet_diagnostic.CA5399.severity = none
+dotnet_diagnostic.CA5400.severity = none
+
+#### Compiler warnings (CS####) ####
+
+# CS1591: Missing XML comment for publicly visible type or member
+# Disabled because although XML documentation is enabled on the project, documenting everything is not always necessary
+dotnet_diagnostic.CS1591.severity = none
diff --git a/src/files/4_ReSharperAnalyzers.editorconfig b/src/files/4_ReSharperAnalyzers.editorconfig
new file mode 100644
index 0000000..cb7bf56
--- /dev/null
+++ b/src/files/4_ReSharperAnalyzers.editorconfig
@@ -0,0 +1,10 @@
+is_global = true
+global_level = -1
+
+# Disable some ReSharper / Rider inspections already covered by .NET analyzers
+
+# Already covered by IDE0130
+resharper_check_namespace_highlighting = none
+
+# Already covered by file defaults "insert_final_newline"
+csharp_insert_final_newline = false
diff --git a/src/files/5_TestProjectsAnalyzers.editorconfig b/src/files/5_TestProjectsAnalyzers.editorconfig
new file mode 100644
index 0000000..df2d922
--- /dev/null
+++ b/src/files/5_TestProjectsAnalyzers.editorconfig
@@ -0,0 +1,11 @@
+# global_level must be higher than the .NET Analyzer files
+is_global = true
+global_level = 0
+
+# GMNG01: Add 'IndexBy' or 'NoIndexNeeded' attributes on the containing type
+# Disabled because specifying MongoDB indexes is only required for production code, not for test projects
+dotnet_diagnostic.GMNG01.severity = none
+
+# GMDTR12: Use method ending with 'Async' instead
+# Disabled because our MediatR static extension method that ends with "Async" cannot be mocked in unit tests so developers have to use the "Send" method instead
+dotnet_diagnostic.GMDTR12.severity = none
diff --git a/src/files/BannedSymbols.txt b/src/files/BannedSymbols.txt
new file mode 100644
index 0000000..071608a
--- /dev/null
+++ b/src/files/BannedSymbols.txt
@@ -0,0 +1,3 @@
+P:System.DateTime.Now;Use System.DateTime.UtcNow instead.
+P:System.DateTimeOffset.Now;Use System.DateTimeOffset.UtcNow instead.
+P:System.DateTimeOffset.DateTime;Use System.DateTimeOffset.UtcDateTime instead.