This commit is contained in:
DotNet Bot 2023-05-23 09:38:10 +10:00 коммит произвёл Igor Velikorossov
Коммит a8c95411ab
2279 изменённых файлов: 208138 добавлений и 0 удалений

30
.config/dotnet-tools.json Normal file
Просмотреть файл

@ -0,0 +1,30 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-coverage": {
"version": "17.6.9",
"commands": [
"dotnet-coverage"
]
},
"dotnet-reportgenerator-globaltool": {
"version": "5.1.19",
"commands": [
"reportgenerator"
]
},
"microsoft.visualstudio.slngen.tool": {
"version": "9.5.3",
"commands": [
"slngen"
]
},
"PowerShell": {
"version": "7.3.3",
"commands": [
"pwsh"
]
}
}
}

Просмотреть файл

@ -0,0 +1,47 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/dotnet
{
"name": "C# (.NET)",
"image": "mcr.microsoft.com/devcontainers/dotnet:0-6.0-focal",
"hostRequirements": {
"cpus": 4,
"memory": "8gb"
},
"features": {
"ghcr.io/devcontainers/features/github-cli:1": {}
},
// Configure tool-specific properties.
"customizations": {
// Configure properties specific to VS Code.
"vscode": {
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-dotnettools.csharp"
],
"settings": {
// Loading projects on demand is better for larger codebases
"omnisharp.enableMsBuildLoadProjectsOnDemand": true,
"omnisharp.enableRoslynAnalyzers": true,
"omnisharp.enableEditorConfigSupport": true,
"omnisharp.enableAsyncCompletion": true,
"omnisharp.testRunSettings": "${containerWorkspaceFolder}/artifacts/obj/vscode/.runsettings"
}
}
},
// Use 'onCreateCommand' to run pre-build commands inside the codespace
"onCreateCommand": "${containerWorkspaceFolder}/.devcontainer/scripts/onCreateCommand.sh",
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "${containerWorkspaceFolder}/.devcontainer/scripts/postCreateCommand.sh",
// Add the locally installed dotnet to the path to ensure that it is activated
// This allows developers to just use 'dotnet build' on the command-line, and the local dotnet version will be used.
"remoteEnv": {
"PATH": "${containerWorkspaceFolder}/.dotnet:${containerEnv:PATH}",
"DOTNET_MULTILEVEL_LOOKUP": "0"
},
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "vscode"
}

Просмотреть файл

@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -e
# Dev Container can run out of disk space if we try to build all TFMs, so only build net8.0
echo "net8.0" > .targetframeworks
# Build the repo
./build.sh
# save the commit hash of the currently built assemblies, so developers know which version was built
git rev-parse HEAD > ./artifacts/prebuild.sha

Просмотреть файл

@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -e
# reset the repo to the commit hash that was used to build the prebuilt Codespace
git reset --hard $(cat ./artifacts/prebuild.sha)

22
.editorconfig Normal file
Просмотреть файл

@ -0,0 +1,22 @@
# Remove the line below if you want to inherit .editorconfig settings from higher directories
root = true
[*]
indent_size = 4
indent_style = space
tab_width = 4
insert_final_newline = true
trim_trailing_whitespace = true
spelling_languages = en-us
spelling_checkable_types = strings,identifiers,comments
spelling_error_severity = information
spelling_exclusion_path = .\eng\spellchecking_exclusions.dic
file_header_template = Licensed to the .NET Foundation under one or more agreements.\nThe .NET Foundation licenses this file to you under the MIT license.
[*.{appxmanifest,axml,build,config,csproj,dbml,discomap,dtd,json,jsproj,lsproj,njsproj,nuspec,proj,props,resjson,resw,resx,StyleCop,targets,tasks,vbproj,yml,xml,xsd}]
indent_style = space
indent_size = 2
tab_width = 2

63
.gitattributes поставляемый Normal file
Просмотреть файл

@ -0,0 +1,63 @@
# https://help.github.com/articles/dealing-with-line-endings/
# 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
# 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
*.png filter=lfs diff=lfs merge=lfs -text
*.jpg filter=lfs diff=lfs merge=lfs -text
*.dll filter=lfs diff=lfs merge=lfs -text

83
.github/ISSUE_TEMPLATE/01_bug_report.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,83 @@
name: Bug Report
description: Create a report to help us improve
labels: ["untriaged", "bug"]
body:
- type: markdown
attributes:
value: |
We welcome bug reports! Please see our [contribution guidelines](https://github.com/dotnet/r9/blob/main/CONTRIBUTING.md#writing-a-good-bug-report) for more information on writing a good bug report. This template will help us gather the information we need to start the triage process.
- type: textarea
id: background
attributes:
label: Description
description: Please share a clear and concise description of the problem.
placeholder: Description
validations:
required: true
- type: textarea
id: repro-steps
attributes:
label: Reproduction Steps
description: |
Please include minimal steps to reproduce the problem, if possible. E.g.: the smallest possible code snippet; or a small project, with steps to run it. If possible include text as text rather than screenshots (so it shows up in searches).
placeholder: Minimal Reproduction
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: Expected behavior
description: |
Provide a description of the expected behavior.
placeholder: Expected behavior
validations:
required: true
- type: textarea
id: actual-behavior
attributes:
label: Actual behavior
description: |
Provide a description of the actual behavior observed. If applicable please include any error messages, exception stacktraces or memory dumps.
placeholder: Actual behavior
validations:
required: true
- type: textarea
id: regression
attributes:
label: Regression?
description: |
Did this work in a previous build or release of .NET R9? If you can try a previous release or build to find out, that can help us narrow down the problem. If you don't know, that's OK.
placeholder: Regression?
validations:
required: false
- type: textarea
id: known-workarounds
attributes:
label: Known Workarounds
description: |
Please provide a description of any known workarounds.
placeholder: Known Workarounds
validations:
required: false
- type: textarea
id: configuration
attributes:
label: Configuration
description: |
Please provide more information on your .NET configuration:
* Which version of .NET is the code running on? E.g., '7.0 Preview1', or daily build number, use `dotnet --info`.
* What OS and version, and what distro, if applicable?
* Do you know whether it is specific to that configuration?
* If you're using Blazor, which web browser(s) do you see this issue in?
placeholder: Configuration
validations:
required: false
- type: textarea
id: other-info
attributes:
label: Other information
description: |
If you have an idea where the problem might lie, let us know that here. Please include any pointers to code, relevant changes, or related issues you know of.
placeholder: Other information
validations:
required: false

74
.github/ISSUE_TEMPLATE/02_api_proposal.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,74 @@
name: API Suggestion
description: Propose a change to the public API surface
title: "[API Proposal]: "
labels: ["untriaged", "api-suggestion"]
body:
- type: markdown
attributes:
value: |
We welcome API proposals! We have a process to evaluate the value and shape of new API. There is an overview of our process [here](https://github.com/dotnet/runtime/blob/main/docs/project/api-review-process.md). This template will help us gather the information we need to start the review process.
- type: textarea
id: background
attributes:
label: Background and motivation
description: Please describe the purpose and value of the new API here.
placeholder: Purpose
validations:
required: true
- type: textarea
id: api-proposal
attributes:
label: API Proposal
description: |
Please provide the specific public API signature diff that you are proposing.
You may find the [Framework Design Guidelines](https://github.com/dotnet/runtime/blob/main/docs/coding-guidelines/framework-design-guidelines-digest.md) helpful.
placeholder: API declaration (no method bodies)
value: |
```csharp
namespace System.Collections.Generic;
public class MyFancyCollection<T> : IEnumerable<T>
{
public void Fancy(T item);
}
```
validations:
required: true
- type: textarea
id: api-usage
attributes:
label: API Usage
description: |
Please provide code examples that highlight how the proposed API additions are meant to be consumed. This will help suggest whether the API has the right shape to be functional, performant and usable.
placeholder: API usage
value: |
```csharp
// Fancy the value
var c = new MyFancyCollection<int>();
c.Fancy(42);
// Getting the values out
foreach (var v in c)
Console.WriteLine(v);
```
validations:
required: true
- type: textarea
id: alternative-designs
attributes:
label: Alternative Designs
description: |
Please provide alternative designs. This might not be APIs; for example instead of providing new APIs an option might be to change the behavior of an existing API.
placeholder: Alternative designs
validations:
required: false
- type: textarea
id: risks
attributes:
label: Risks
description: |
Please mention any risks that to your knowledge the API proposal might entail, such as breaking changes, performance regressions, etc.
placeholder: Risks
validations:
required: false

8
.github/ISSUE_TEMPLATE/03_blank_issue.md поставляемый Normal file
Просмотреть файл

@ -0,0 +1,8 @@
---
name: Blank issue
about: Something that doesn't fit the other categories
title: ''
labels: 'untriaged'
assignees: ''
---

14
.github/ISSUE_TEMPLATE/config.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,14 @@
blank_issues_enabled: true
contact_links:
- name: Issue with R9 extensions for Azure
url: https://github.com/azure/r9/issues/new/choose
about: Please open issues relating to R9 extensions for Azure in azure/r9.
- name: Issue with ASP.NET Core
url: https://github.com/dotnet/aspnetcore/issues/new/choose
about: Please open issues relating to ASP.NET Core in dotnet/aspnetcore.
- name: Issue with .NET runtime or core .NET libraries
url: https://github.com/dotnet/runtime/issues/new/choose
about: Please open issues with the .NET runtime or core in their repo
- name: Issue with .NET SDK
url: https://github.com/dotnet/sdk/issues/new/choose
about: Please open issues relating to the .NET SDK in dotnet/sdk.

313
.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,313 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# Tool Runtime Dir
# note: there is no trailing slash so if these are symlinks (which are seen as files,
# instead of directories), git will still ignore them.
.dotnet
.dotnet-mono
.dotnet-tools-global
.packages
.tools
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
*.sln
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
!/eng/Release/
[Rr]eleases/
!/docs/releases/
[Xx]64/
[Xx]86/
[Bb]uild/
bld/
[Bb]in/
[Oo]bj/
# Visual Studio 2015 cache/options directory
.vs/
.build/
.vscode
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# 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
# TODO: Un-comment the next line if you do not want to checkin
# your web deploy settings because they may include unencrypted
# passwords
#*.pubxml
*.publishproj
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
packages/*
packages
# except build/, which is used as an MSBuild target.
!packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
!src/Packages
!eng/Packages
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Microsoft Azure ApplicationInsights config file
ApplicationInsights.config
# Windows Store app package directory
AppPackages/
BundleArtifacts/
# 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
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# 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
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# LightSwitch generated files
GeneratedArtifacts/
ModelManifest.xml
# Paket dependency manager
.paket/paket.exe
# FAKE - F# Make
.fake/
PubsubService/ServiceConfiguration.cscfg
# Microsoft.Cloud.InstrumentationFramework.Metrics
*Ifx*.lib
*Ifx*.dll
*Tfx*.lib
*Tfx*.dll
*120.dll
TfxPerfCounter.man
# Meta directories
.packages/*/*
# Rider
.idea/
!src/MetaPackages/Sdk/build
!eng/Build
packages.lock.json
PackageInfo.json
ProjectInfo.json
docs/_site
docs/obj
docs/refdocs/Microsoft.*.yml
docs/refdocs/Project.*.yml
docs/refdocs/toc.yml
docs/refdocs/.manifest
docs/packages/index.md
docs/binaries
BenchmarkDotNet.Artifacts/*
!test/Extensions/Cryptography.Test/TestVectors/Files/*.rsp
# local mutation testing
git-diff.txt
mutation-report.json
mutation-report.html
*.sln
*.metaproj
**/launchSettings.json
BenchmarkDotNet.artifacts/
/out.txt
/.targetframeworks
/_TEST
*.binlog
/docs/releases/r9-packages.md

392
.spelling Normal file
Просмотреть файл

@ -0,0 +1,392 @@
.NET
2.x
3.x
4.6x
4.7x
4.8x
5xx
6.a
6.c
6.f
AAD
AAD
abstractions
ad
Agentless
Aggregator
aggregators
AKS
AKV
AKVs
Alexey
analyzer
Analyzers
Andrey
API
APIs
AppInsights
approvers
ASP.NET
ASP.NET.
async
ATM
Authenticode
Autofac
awaitable
AzSecPack
Azure
backend
Backoff
base64
Base64
Behavior
Belenko
Bezdolny
Binskim
Blackforest
Blazek
bloomfilter
bloomfilters
boolean
bootstrapper
buildout
Brownbag
Brownbags
byte
C#
Caching
CAE
callee
callouts
Callouts
CDPx
Chainable
checkboxes
checkin
cmdlets
cmdlet
CNAME
CNAME
CNAMEs
CNAMEs
codebase
codebases
COGs
combinators
composability
composable
composable
config
Config
CoreAuth
CoreAuth
correlators
cpu
CPU
cross-cutting
cross-cutting
Crypto
cscfg
customizable
Cv2
DCs
decorrelated
Deepak
Deliverables
deserialization
deserialize
deserialized
dev
DevOps
DGrep
discoverability
dockerize
DoD
dogfood
Dogfood
dont's
dotnet
dSMS
e.g.
ECS
ECS
ejuvenate
encodings
eng.ms
enricher
Enricher
enrichers
Enrichers
enum
enums
Ev2
executables
external_bp
failover
filename
FlatBuffer
FlatBuffers
FlatSharp
flighting
FluentD
formatters
fulfill
FxCop
Gallatin
Gameday
Gamedays
Gantt
Generators
geneva
geo
geos
getters
github
Golang-ci
gRPC
GuestUser
hoc
hotfix
hotfixes
how-tos
http
HTTP
HttpClient
https
i.e.
IC3
IDWeb
ifx
Ihar
In-proc
indempotent
InfoSec
InfoSec
initializer
initializers
Initializers
injectable
injectable
inlining
IntelliSense
interoperate
intrinsic
intrinsics
IoC
iOS
JSON
JSON-encoded
Juraj
Klauco
Kubernetes
Kusto
learnings
lifecycle
lightbulb
LinkedIn
Liron
livesite
Logging
lookups
Malkevich
Marcano
Matej
McAllister
MdmMetricReporter
memoization
memoize
memoized
metadata
microservice
microservices
Microsoft
microsoft.com
middleware
middlewares
Miri
miscomputed
Mise
Mise
MISE
MISE
mitigation
mitigations
Mitrache
Modi
Mooncake
MSBuild
MSGraph
MSGraph
MSI
MSIs
mutator
MyAccess
naïve
namespace
namespaces
natively
natively
Newtonsoft
NLog
Noskov
ns
NuGet
NuGets
nullability
nullable
onboard
onboarded
onboarding
onboards
OneBranch
OneCert
OneDrive
OneObservability
OpenTelemetry
OSS
OTel
OTEPs
PaaSv1
parallelization
parameterless
pdf
Perfmon
PerfPanel
PerfView
pluggability
POCO
POCOs
Polly
Polly.NET
Postconfiguration
PowerShell
ppe
Pranav
pre
pre-aggregated
pre-aggregation
pre-built
pre-release
pre-requisite
preaggregate
preaggregates
preallocated
Preconfiguration
preconfigured
preformatted
preimage
prepending
prober
programmatically
Protobuf
Protobuf-net
PubSub
QoS
quantiles
R9
R9_RELEASE
R9A000
R9A001
R9A002
R9G000
R9G001
R9G002
R9G003
R9G004
R9G005
R9G006
R9G007
R9G008
R9G009
R9G010
r9support
Ramati
ramping
RDFE
reconfigure
Redis
reimplementation
remediations
repo
repos
Ring0
Ring1
rollout
rollouts
Rousos
routable
runtime
runtimes
Saares
SAL
schemas
Scortzario
sdf
SDK
SDKs
seatbelt
serializer
serializers
Serilog
ServiceTree
Sev3
SharePoint
Shearar
Shiproom
Shullo
Simmy
SimpleInjector
Skowronski
Skype
Skypetoken
SLA
SLAs
snappable
standalone
stateful
struct
structs
Stryker
Stryker.NET
substring
SumObserver
suppressions
Tal
teams-service-mwt-fae-data-service
timestamp
Tomka
toolchain
toolchains
toolset
Trouter
TRv2
uncheck
unmanaged
unredacted
uri
URI
v1.3
v1.4
v1.6
validator
validators
versionable
versioned
versioning
Versioning
Virtualization
virtualization
VM
WebAuth
WebHost
WebRTC
whitespace
Wiki
wildcard
Win32
Workstream
Workstreams
xmls
xUnit
xxHash
Zipkin

9
CODE_OF_CONDUCT.md Normal file
Просмотреть файл

@ -0,0 +1,9 @@
# Microsoft Open Source Code of Conduct
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
Resources:
- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns

191
CONTRIBUTING.md Normal file
Просмотреть файл

@ -0,0 +1,191 @@
# Contributing Guide
> :warning: Please note, this document is a subset of [Contributing to .NET Runtime][net-contributing], make sure to read it first.
* [Reporting Issues](#reporting-issues)
+ [Identify Where to Report](#identify-where-to-report)
+ [Finding Existing Issues](#finding-existing-issues)
+ [Writing a Good API Proposal](#writing-a-good-api-proposal)
+ [Writing a Good Bug Report](#writing-a-good-bug-report)
- [Why are Minimal Reproductions Important?](#why-are-minimal-reproductions-important)
- [Are Minimal Reproductions Required?](#are-minimal-reproductions-required)
- [How to Create a Minimal Reproduction](#how-to-create-a-minimal-reproduction)
* [Contributing Changes](#contributing-changes)
+ [DOs and DON'Ts](#dos-and-donts)
+ [Breaking Changes](#breaking-changes)
+ [Suggested Workflow](#suggested-workflow)
+ [Commit Messages](#commit-messages)
+ [PR Feedback](#pr-feedback)
+ [Help Wanted (Up for Grabs)](#help-wanted-up-for-grabs)
+ [Contributor License Agreement](#contributor-license-agreement)
You can contribute to R9 with issues, pull-requests, and general reviews of both issues and pull-requests. Simply filing issues for problems you encounter is a great way to contribute. Contributing implementations is greatly appreciated.
## Reporting Issues
We always welcome bug reports, API proposals and overall feedback. Here are a few tips on how you can make reporting your issue as effective as possible.
### Identify Where to Report
The .NET codebase is distributed across multiple repositories in the [.NET organization](https://github.com/dotnet). Depending on the feedback you might want to file the issue on a different repo. Here are a few common repos:
* [dotnet/runtime](https://github.com/dotnet/runtime) .NET runtime, libraries and shared host installers.
* [dotnet/aspnetcore](https://github.com/dotnet/aspnetcore) ASP.NET Core.
* [azure/r9](https://github.com/azure/r9) R9 extensions for Azure.
### Finding Existing Issues
Before filing a new issue, please search our [open issues](https://github.com/dotnet/runtime/issues) to check if it already exists.
If you do find an existing issue, please include your own feedback in the discussion. Do consider upvoting (👍 reaction) the original post, as this helps us prioritize popular issues in our backlog.
### Writing a Good API Proposal
Please review our [API review process](https://github.com/dotnet/runtime/blob/main/docs/project/api-review-process.md) documents for guidelines on how to submit an API review. When ready to submit a proposal, please use the [API Suggestion issue template](https://github.com/dotnet/runtime/issues/new?assignees=&labels=api-suggestion&template=02_api_proposal.yml&title=%5BAPI+Proposal%5D%3A+).
### Writing a Good Bug Report
Good bug reports make it easier for maintainers to verify and root cause the underlying problem. The better a bug report, the faster the problem will be resolved. Ideally, a bug report should contain the following information:
* A high-level description of the problem.
* A _minimal reproduction_, i.e. the smallest size of code/configuration required to reproduce the wrong behavior.
* A description of the _expected behavior_, contrasted with the _actual behavior_ observed.
* Information on the environment: OS/distro, CPU arch, SDK version, etc.
* Additional information, e.g. is it a regression from previous versions? are there any known workarounds?
When ready to submit a bug report, please use the [Bug Report issue template](https://github.com/dotnet/runtime/issues/new?assignees=&labels=&template=01_bug_report.yml).
#### Why are Minimal Reproductions Important?
A reproduction lets maintainers verify the presence of a bug, and diagnose the issue using a debugger. A _minimal_ reproduction is the smallest possible console application demonstrating that bug. Minimal reproductions are generally preferable since they:
1. Focus debugging efforts on a simple code snippet,
2. Ensure that the problem is not caused by unrelated dependencies/configuration,
3. Avoid the need to share production codebases.
#### Are Minimal Reproductions Required?
In certain cases, creating a minimal reproduction might not be practical (e.g. due to nondeterministic factors, external dependencies). In such cases you would be asked to provide as much information as possible, for example by sharing a memory dump of the failing application. If maintainers are unable to root cause the problem, they might still close the issue as not actionable. While not required, minimal reproductions are strongly encouraged and will significantly improve the chances of your issue being prioritized and fixed by the maintainers.
#### How to Create a Minimal Reproduction
The best way to create a minimal reproduction is gradually removing code and dependencies from a reproducing app, until the problem no longer occurs. A good minimal reproduction:
* Excludes all unnecessary types, methods, code blocks, source files, nuget dependencies and project configurations.
* Contains documentation or code comments illustrating expected vs actual behavior.
* If possible, avoids performing any unneeded IO or system calls. For example, can the ASP.NET based reproduction be converted to a plain old console app?
## Contributing Changes
Project maintainers will merge changes that improve the product significantly.
The [Pull Request Guide][pr-guide] and [Copyright][copyright-guide] docs define additional guidance.
### DOs and DON'Ts
Please do:
* **DO** follow our [coding style][coding-style] (C# code-specific)<br/>
We strive to wrap the lines around 120 mark, and it's acceptable to stretch to no more than 150 chars (with some exceptions being URLs). [EditorGuidelines VS extension](https://marketplace.visualstudio.com/items?itemName=PaulHarrington.EditorGuidelines) makes it easier to visualise (see https://github.com/dotnet/winforms/pull/4836).
* **DO** give priority to the current style of the project or file you're changing even if it diverges from the general guidelines.
* **DO** include tests when adding new features. When fixing bugs, start with
adding a test that highlights how the current behavior is broken.
* **DO** keep the discussions focused. When a new or related topic comes up
it's often better to create new issue than to side track the discussion.
* **DO** blog and tweet (or whatever) about your contributions, frequently!
Please do not:
* **DON'T** make PRs for style changes.
* **DON'T** surprise us with big pull requests. Instead, file an issue and start
a discussion so we can agree on a direction before you invest a large amount
of time.
* **DON'T** commit code that you didn't write. If you find code that you think is a good fit to add to .NET Core, file an issue and start a discussion before proceeding.
* **DON'T** submit PRs that alter licensing related files or headers. If you believe there's a problem with them, file an issue and we'll be happy to discuss it.
* **DON'T** add API additions without filing an issue and discussing with us first. See [API Review Process][api-review-process].
### Breaking Changes
Contributions must maintain [API signature][breaking-changes-public-contract] and behavioral compatibility. Contributions that include [breaking changes][breaking-changes] will be rejected. Please file an issue to discuss your idea or change if you believe that it may affect managed code compatibility.
### Suggested Workflow
We use and recommend the following workflow:
1. Create an issue for your work.
- You can skip this step for trivial changes.
- Reuse an existing issue on the topic, if there is one.
- Get agreement from the team and the community that your proposed change is a good one.
- If your change adds a new API, follow the [API Review Process][api-review-process].
- Clearly state that you are going to take on implementing it, if that's the case. You can request that the issue be assigned to you. Note: The issue filer and the implementer don't have to be the same person.
2. Create a personal fork of the repository on GitHub (if you don't already have one).
3. In your fork, create a branch off of main (`git checkout -b mybranch`).
- Name the branch so that it clearly communicates your intentions, such as issue-123 or githubhandle-issue.
- Branches are useful since they isolate your changes from incoming changes from upstream. They also enable you to create multiple PRs from the same fork.
4. Make and commit your changes to your branch.
- [Workflow Instructions](docs/building.md) explains how to build and test.
- Please follow our [Commit Messages](#commit-messages) guidance.
5. Add new tests corresponding to your change, if applicable.
6. Build the repository with your changes.
- Make sure that the builds are clean.
- Make sure that the tests are all passing, including your new tests.
7. Create a pull request (PR) against the dotnet/runtime repository's **main** branch.
- State in the description what issue or improvement your change is addressing.
- Check if all the Continuous Integration checks are passing.
8. Wait for feedback or approval of your changes from the area owners.
- Details about the pull request [review procedure](docs/pr-guide.md).
9. When area owners have signed off, and all checks are green, your PR will be merged.
- The next official build will automatically include your change.
- You can delete the branch you used for making the change.
### Commit Messages
Please format commit messages as follows (based on [A Note About Git Commit Messages][note-about-git-commit-messages]). Also, use the [GitHub keywords][github-keywords]:
```
Summarize change in 50 characters or less
Fixes #42
Provide more detail after the first line. Leave one blank line below the
summary and wrap all lines at 72 characters or less.
If the change fixes an issue, leave another blank line after the final
paragraph and indicate which issue is fixed in the specific format
below.
```
Also do your best to factor commits appropriately, not too large with unrelated things in the same commit, and not too small with the same small change applied N times in N different commits.
### PR Feedback
Project maintainers and community members will provide feedback on your change. Community feedback is highly valued. You will often see the absence of team feedback if the community has already provided good review feedback.
One or more project maintainers members will review every PR prior to merge. They will often reply with "LGTM, modulo comments". That means that the PR will be merged once the feedback is resolved. "LGTM" == "looks good to me".
There are lots of thoughts and [approaches](https://github.com/antlr/antlr4-cpp/blob/master/CONTRIBUTING.md#emoji) for how to efficiently discuss changes. It is best to be clear and explicit with your feedback. Please be patient with people who might not understand the finer details about your approach to feedback.
### Help Wanted (Up for Grabs)
The team marks the most straightforward issues as [help wanted](https://github.com/dotnet/r9/labels/help%20wanted). This set of issues is the place to start if you are interested in contributing but new to the codebase.
### Contributor License Agreement
You must sign a [.NET Foundation Contribution License Agreement (CLA)](https://cla.dotnetfoundation.org) before your PR will be merged. This is a one-time requirement for projects in the .NET Foundation. You can read more about [Contribution License Agreements (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) on Wikipedia.
The agreement: [net-foundation-contribution-license-agreement.pdf](https://github.com/dotnet/home/blob/master/guidance/net-foundation-contribution-license-agreement.pdf)
You don't have to do this up-front. You can simply clone, fork, and submit your pull-request as usual. When your pull-request is created, it is classified by a CLA bot. If the change is trivial (for example, you just fixed a typo), then the PR is labelled with `cla-not-required`. Otherwise it's classified as `cla-required`. Once you signed a CLA, the current and all future pull-requests will be labelled as `cla-signed`.
[comment]: <> (URI Links)
[api-review-process]: https://github.com/dotnet/runtime/blob/main/docs/project/api-review-process.md
[breaking-changes]: https://github.com/dotnet/runtime/blob/main/docs/coding-guidelines/breaking-changes.md
[breaking-changes-public-contract]: https://github.com/dotnet/runtime/blob/main/docs/coding-guidelines/breaking-changes.md#bucket-1-public-contract
[coding-style]: https://github.com/dotnet/runtime/blob/master/docs/coding-guidelines/coding-style.md
[copyright-guide]: https://github.com/dotnet/runtime/blob/main/docs/project/copyright.md
[github-keywords]: https://docs.github.com/get-started/writing-on-github/working-with-advanced-formatting/using-keywords-in-issues-and-pull-requests#linking-a-pull-request-to-an-issue
[net-contributing]: https://github.com/dotnet/runtime/blob/main/CONTRIBUTING.md
[note-about-git-commit-messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
[pr-guide]: https://github.com/dotnet/runtime/blob/main/docs/pr-guide.md

107
Directory.Build.props Normal file
Просмотреть файл

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<Import Project="Sdk.props" Sdk="Microsoft.DotNet.Arcade.Sdk" />
<!-- TFMs and their permutations -->
<PropertyGroup>
<TargetFrameworkName>net</TargetFrameworkName>
<TargetFrameworkMajorVersion>8</TargetFrameworkMajorVersion>
<TargetFrameworkMinorVersion>0</TargetFrameworkMinorVersion>
<TargetFrameworkVersion>$(TargetFrameworkMajorVersion).$(TargetFrameworkMinorVersion)</TargetFrameworkVersion>
<!-- The latest TFM we're targeting overall -->
<LatestTargetFramework>$(TargetFrameworkName)$(TargetFrameworkVersion)</LatestTargetFramework>
<!-- All the .NET TFMs we're building -->
<SupportedNetCoreTargetFrameworks>$(LatestTargetFramework);net6.0</SupportedNetCoreTargetFrameworks>
<NetCoreTargetFrameworks>$(SupportedNetCoreTargetFrameworks);netcoreapp3.1</NetCoreTargetFrameworks>
<!-- The minimum supported .NET version for external consumers. This is used for packaging control, see Packaging.targets -->
<MinimumSupportedTfmForPackaging>net6.0</MinimumSupportedTfmForPackaging>
<!-- Limit the .NET TFMs when .targetframeworks is defined -->
<!--
When .targetframeworks exists, only the TFMs listed in this file will be built unless for the projects
which have mandatory TFMs. Variables named $(Conditional[TFM]) will include this TFM only if it should
be built. In projects that can optionally target the TFM use this variable instead of the TFM.
-->
<CustomTargetFrameworks Condition="Exists('$(MSBuildThisFileDirectory)\.targetframeworks')">$([System.IO.File]::ReadAllText('$(MSBuildThisFileDirectory)\.targetframeworks').Trim())</CustomTargetFrameworks>
<SupportedNetCoreTargetFrameworks Condition="'$(CustomTargetFrameworks)' != ''">$(LatestTargetFramework)</SupportedNetCoreTargetFrameworks>
<SupportedNetCoreTargetFrameworks Condition="'$(CustomTargetFrameworks)' != '' AND $(CustomTargetFrameworks.Contains('net6.0'))">$(SupportedNetCoreTargetFrameworks);net6.0</SupportedNetCoreTargetFrameworks>
<NetCoreTargetFrameworks Condition="'$(CustomTargetFrameworks)' != ''">$(SupportedNetCoreTargetFrameworks)</NetCoreTargetFrameworks>
<NetCoreTargetFrameworks Condition="'$(CustomTargetFrameworks)' != '' AND $(CustomTargetFrameworks.Contains('netcoreapp3.1'))">$(NetCoreTargetFrameworks);netcoreapp3.1</NetCoreTargetFrameworks>
<ConditionalNet462 Condition="'$(CustomTargetFrameworks)' == '' OR $(CustomTargetFrameworks.Contains('net462'))">;net462</ConditionalNet462>
</PropertyGroup>
<PropertyGroup>
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<LangVersion>preview</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<DebugType>portable</DebugType>
<DebugSymbols>true</DebugSymbols>
<SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
<RunSettingsFilePath>$(MSBuildThisFileDirectory)\eng\Common.runsettings</RunSettingsFilePath>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<Deterministic>true</Deterministic>
<Features>debug-determinism</Features>
<!-- https://learn.microsoft.com/dotnet/fundamentals/package-validation/overview -->
<EnablePackageValidation>true</EnablePackageValidation>
<EnableXlfLocalization>false</EnableXlfLocalization>
<UpdateXlfOnBuild>false</UpdateXlfOnBuild>
<!--
Opt Arcade-driven (restore.cmd, official build, and CI build) restores into using NuGet's static-graph restore
(https://learn.microsoft.com/nuget/reference/msbuild-targets#restoring-with-msbuild-static-graph-evaluation),
which uses MSBuild's static-graph-construction features to speed up the restore operation.
-->
<RestoreUseStaticGraphEvaluation>true</RestoreUseStaticGraphEvaluation>
<!-- These are explicitly set in src/Analyzers and src/Generators -->
<GenerateNeutralResourcesLanguageAttribute>false</GenerateNeutralResourcesLanguageAttribute>
<!-- Allow SourceLink to work for strongly types resource files (SR) by embedding generated files into the PDBs -->
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<!-- Opt in to build acceleration in VS (from 17.5 onwards): https://github.com/dotnet/project-system/blob/main/docs/build-acceleration.md -->
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
</PropertyGroup>
<!-- https://github.com/dotnet/aspnetcore/blob/72b0269372a/eng/Common.props#L3-L6 -->
<PropertyGroup>
<TargetOsName Condition=" '$(TargetOsName)' == '' AND $([MSBuild]::IsOSPlatform('Windows'))">win</TargetOsName>
<IsWindowsBuild>false</IsWindowsBuild>
<IsWindowsBuild Condition=" '$(TargetOsName)' == 'win' ">true</IsWindowsBuild>
</PropertyGroup>
<!-- TODO: workaround for https://github.com/dotnet/r9/issues/85 -->
<PropertyGroup>
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
</PropertyGroup>
<PropertyGroup Condition="'$(DotNetBuildOffline)' == 'true'">
<!--
Arcade has a special version prop for CodeAnalysis.CSharp in GenFacades
to try to match the version loaded by msbuild. In the offline build, this
is simply the source-built version.
-->
<MsbuildTaskMicrosoftCodeAnalysisCSharpVersion>$(MicrosoftCodeAnalysisCSharpVersion)</MsbuildTaskMicrosoftCodeAnalysisCSharpVersion>
</PropertyGroup>
<Target Name="DisableBrokenAnalyzers" BeforeTargets="CoreCompile">
<ItemGroup>
<Analyzer Remove="@(Analyzer)" Condition="'%(Filename)' == 'Microsoft.Extensions.Configuration.Binder.SourceGeneration'"/>
</ItemGroup>
</Target>
<!-- R9 common properties -->
<Import Project="$(MSBuildThisFileDirectory)\eng\MSBuild\Analyzers.props" />
<Import Project="$(MSBuildThisFileDirectory)\eng\MSBuild\Packaging.props" />
<Import Project="$(MSBuildThisFileDirectory)\eng\MSBuild\LegacySupport.props" />
<Import Project="$(MSBuildThisFileDirectory)\eng\MSBuild\Shared.props" />
<Import Project="$(MSBuildThisFileDirectory)\eng\MSBuild\Generators.props" />
</Project>

84
Directory.Build.targets Normal file
Просмотреть файл

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<Import Project="Sdk.targets" Sdk="Microsoft.DotNet.Arcade.Sdk" />
<Import Project="$(MSBuildThisFileDirectory)\eng\MSBuild\Analyzers.targets" />
<Import Project="$(MSBuildThisFileDirectory)\eng\MSBuild\Packaging.targets" />
<Import Project="$(MSBuildThisFileDirectory)\eng\MSBuild\LegacySupport.targets" />
<Import Project="$(MSBuildThisFileDirectory)\eng\MSBuild\Shared.targets" />
<Import Project="$(MSBuildThisFileDirectory)\eng\MSBuild\Generators.targets" />
<Import Project="$(MSBuildThisFileDirectory)\eng\MSBuild\ProjectStaging.targets" />
<!-- Warning stuff -->
<PropertyGroup>
<MSBuildWarningsAsMessages>$(MSBuildWarningsAsMessages);NETSDK1138;MSB3270</MSBuildWarningsAsMessages>
<WarningLevel>5</WarningLevel>
<!-- This is false for local development, but set to true in the CI system -->
<TreatWarningsAsErrors Condition=" '$(TreatWarningsAsErrors)' == '' ">false</TreatWarningsAsErrors>
<!-- TODO: to be reenabled and all warnings fixed (https://github.com/dotnet/r9/issues/177) -->
<NoWarn>$(NoWarn);IL2026;IL2087;IL2067;IL2075;IL2091;IL2072;IL2090;CA1825;IL2070;IL2098;IL2057</NoWarn>
<!-- Prevent analyzer crashes from stopping things -->
<NoWarn>$(NoWarn);AD0001</NoWarn>
<!-- R9A029 is for R9 customers, not for R9 itself -->
<NoWarn>$(NoWarn);R9A029</NoWarn>
<!-- Temporary -->
<NoWarn>$(NoWarn);R9A049</NoWarn>
<!-- NU5104: A stable release of a package should not have a prerelease dependency -->
<NoWarn>$(NoWarn);NU5104</NoWarn>
<NoWarn Condition="'$(GenerateDocumentationFile)' != 'true'">$(NoWarn);SA1600;SA0001</NoWarn>
<!-- Legacy targets do not support attributes for a nullable context thus suppressing null check warnings -->
<NoWarn Condition="'$(TargetFramework)' == 'net462' or '$(TargetFramework)' == 'net472' or '$(TargetFramework)' == 'netstandard2.0'">$(NoWarn);CA1062</NoWarn>
</PropertyGroup>
<!-- .NET 8 specific configurations (https://github.com/dotnet/r9/issues/177) -->
<PropertyGroup Condition="'$(TargetFramework)' == 'net8.0'">
<!-- Ignore ASP0019: Use IHeaderDictionary.Append or the indexer to append or set headers. IDictionary.Add will throw an ArgumentException when attempting to add a duplicate key -->
<NoWarn>$(NoWarn);ASP0019</NoWarn>
</PropertyGroup>
<PropertyGroup>
<!-- Ignore RS1024: Compare symbols correctly (https://github.com/dotnet/r9/issues/177) -->
<NoWarn>$(NoWarn);RS1024</NoWarn>
</PropertyGroup>
<!-- Ignore SuppressTfmSupportBuildWarnings warning for .NET Core 3.1 due to System.Diagnostic.DiagnosticSource 7.0.0 version -->
<PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
</PropertyGroup>
<ItemGroup Condition="'$(Stage)' == 'dev' AND '$(OutputType)' != 'Exe' AND '$(Api)' != 'false'">
<AssemblyAttribute Include="System.Diagnostics.CodeAnalysis.ExperimentalAttribute" />
</ItemGroup>
<Target Name="AddInternalsVisibleToDynamicProxyGenAssembly2" BeforeTargets="BeforeCompile">
<ItemGroup Condition="'@(InternalsVisibleToDynamicProxyGenAssembly2->Count())' &gt; 0">
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1 Condition="'$(SignArtifacts)' == 'true' ">DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7</_Parameter1>
<_Parameter1 Condition="'$(SignArtifacts)' != 'true' ">DynamicProxyGenAssembly2</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
</Target>
<Target Name="AddInternalsVisibleToTest" Condition="'$(BuildTests)'!='false'" BeforeTargets="BeforeCompile">
<ItemGroup Condition="'@(InternalsVisibleToTest->Count())' &gt; 0">
<InternalsVisibleTo Include="%(InternalsVisibleToTest.Identity)" />
</ItemGroup>
</Target>
<Target Name="_ConfigureTestRunnerAdditionalArguments" BeforeTargets="_InnerGetTestsToRun">
<PropertyGroup>
<!-- See https://learn.microsoft.com/dotnet/core/tools/dotnet-test -->
<_BlameArgs>--blame --blame-crash --blame-crash-dump-type full --blame-hang --blame-hang-dump-type full --blame-hang-timeout 6m</_BlameArgs>
<!-- This property is used by the Arcade SDK while bootstrapping the VS Test runner -->
<TestRunnerAdditionalArguments>$(TestRunnerAdditionalArguments) $(_BlameArgs)</TestRunnerAdditionalArguments>
</PropertyGroup>
</Target>
</Project>

6
Directory.Packages.props Normal file
Просмотреть файл

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildThisFileDirectory)\eng\Packages\BuildOnly.props" />
<Import Project="$(MSBuildThisFileDirectory)\eng\Packages\General.props" />
<Import Project="$(MSBuildThisFileDirectory)\eng\Packages\TestOnly.props" />
</Project>

23
LICENSE Normal file
Просмотреть файл

@ -0,0 +1,23 @@
The MIT License (MIT)
Copyright (c) .NET Foundation. All rights reserved.
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

37
NuGet.config Normal file
Просмотреть файл

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<!-- Arcade -->
<add key="dotnet-public" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json" />
<add key="dotnet-eng" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json" />
<add key="dotnet-tools" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" />
<add key="dotnet8" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json" />
<add key="dotnet8-transport" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8-transport/nuget/v3/index.json" />
<!-- Used for the Rich Navigation indexing task -->
<add key="richnav" value="https://pkgs.dev.azure.com/azure-public/vside/_packaging/vs-buildservices/nuget/v3/index.json" />
</packageSources>
<!-- Define mappings by adding package patterns beneath the target source.
https://aka.ms/nuget-package-source-mapping -->
<packageSourceMapping>
<packageSource key="dotnet-public">
<package pattern="*" />
</packageSource>
<packageSource key="dotnet-eng">
<package pattern="*" />
</packageSource>
<packageSource key="dotnet-tools">
<package pattern="*" />
</packageSource>
<packageSource key="dotnet8">
<package pattern="*" />
</packageSource>
<packageSource key="dotnet8-transport">
<package pattern="*" />
</packageSource>
<packageSource key="richnav">
<package pattern="*" />
</packageSource>
</packageSourceMapping>
<disabledPackageSources />
</configuration>

58
README.md Normal file
Просмотреть файл

@ -0,0 +1,58 @@
# Enriched Capabilities
This repository contains a suite of libraries that provide facilities commonly needed when creating production-ready applications. Initially developed to support high-scale and high-availability services within Microsoft, such as Microsoft Teams, these libraries deliver functionality that can help make applications more efficient, more robust, and more manageable.
The code in this repo is preliminary and will be released in stable form with .NET 8
The major functional areas this repo addresses are:
- Compliance: Mechanisms to help manage application data according to privacy regulations and policies, which includes a data annotation framework, supporting analyzers, audit report generation, and telemetry redaction.
- Diagnostics: Provides a set of APIs that can be used to gather and report diagnostic information about the health of a service.
- Contextual Options: Extends the .NET Options model to enable experimentations in production.
- Resilience: Builds on top of the popular Polly library to provide sophisticated resilience pipelines along with support for chaos engineering to make applications robust to transient errors.
- Telemetry: Sophisticated telemetry facilities provide enhanced logging, metering, tracing, and latency measuring functionality.
- AspNetCore extensions: Provides different middlewares and extensions that can be used to build high-performance and high-availability ASP.NET Core services.
- Cloud Abstractions: A growing set of abstractions representing common cloud-native service types, making it possible to write applications that can work across multiple cloud providers with relative ease.
- Static Analysis: Provides a set of Roslyn analyzers that can be used to enforce best practices and coding standards.
- Testing: Dramatically simplifies testing around common .NET abstractions such as ILogger and the TimeProvider.
[![Build Status](https://dev.azure.com/dnceng/internal/_apis/build/status/r9/dotnet-r9?branchName=main)](https://dev.azure.com/dnceng/internal/_build/latest?definitionId=1223&branchName=main)
[![Help Wanted](https://img.shields.io/github/issues/dotnet/r9/help%20wanted?style=flat-square&color=%232EA043&label=help%20wanted)](https://github.com/dotnet/r9/labels/help%20wanted)
[![Discord](https://img.shields.io/discord/732297728826277939?style=flat-square&label=Discord&logo=discord&logoColor=white&color=7289DA)](https://aka.ms/dotnet-discord)
## How can I contribute?
We welcome contributions! Many people all over the world have helped make this project better.
* [Contributing](CONTRIBUTING.md) explains what kinds of contributions we welcome
* [Build instructions](docs/building.md) explains how to build and test
## Reporting security issues and security bugs
Security issues and bugs should be reported privately, via email, to the Microsoft Security Response Center (MSRC) <secure@microsoft.com>. You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Further information, including the MSRC PGP key, can be found in the [Security TechCenter](https://www.microsoft.com/msrc/faqs-report-an-issue). You can also find these instructions in this repo's [Security doc](SECURITY.md).
Also see info about related [Microsoft .NET Core and ASP.NET Core Bug Bounty Program](https://www.microsoft.com/msrc/bounty-dot-net-core).
## Useful Links
* [.NET Core source index](https://source.dot.net) / [.NET Framework source index](https://referencesource.microsoft.com)
* [API Reference docs](https://docs.microsoft.com/dotnet/api)
* [.NET API Catalog](https://apisof.net) (incl. APIs from daily builds and API usage info)
* [API docs writing guidelines](https://github.com/dotnet/dotnet-api-docs/wiki) - useful when writing /// comments
* [.NET Discord Server](https://aka.ms/dotnet-discord) - a place to discuss the development of .NET and its ecosystem
## .NET Foundation
This project is a [.NET Foundation](https://www.dotnetfoundation.org/projects) project.
There are many .NET related projects on GitHub.
* [.NET home repo](https://github.com/Microsoft/dotnet) - links to 100s of .NET projects, from Microsoft and the community.
* [ASP.NET Core home](https://docs.microsoft.com/aspnet/core) - the best place to start learning about ASP.NET Core.
This project has adopted the code of conduct defined by the [Contributor Covenant](https://contributor-covenant.org) to clarify expected behavior in our community. For more information, see the [.NET Foundation Code of Conduct](https://www.dotnetfoundation.org/code-of-conduct).
General .NET OSS discussions: [.NET Foundation Discussions](https://github.com/dotnet-foundation/Home/discussions)
## License
.NET (including the runtime repo) is licensed under the [MIT](LICENSE.TXT) license.

41
SECURITY.md Normal file
Просмотреть файл

@ -0,0 +1,41 @@
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.6 BLOCK -->
## Security
Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below.
## Reporting Security Issues
**Please do not report security vulnerabilities through public GitHub issues.**
Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report).
If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc).
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc).
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
* Full paths of source file(s) related to the manifestation of the issue
* The location of the affected source code (tag/branch/commit or direct URL)
* Any special configuration required to reproduce the issue
* Step-by-step instructions to reproduce the issue
* Proof-of-concept or exploit code (if possible)
* Impact of the issue, including how an attacker might exploit the issue
This information will help us triage your report more quickly.
If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs.
## Preferred Languages
We prefer all communications to be in English.
## Policy
Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd).
<!-- END MICROSOFT SECURITY.MD BLOCK -->

286
azure-pipelines.yml Normal file
Просмотреть файл

@ -0,0 +1,286 @@
# Setting batch to true, triggers one build at a time.
# if there is a push while a build in progress, it will wait,
# until the running build finishes, and produce a build with all the changes
# that happened during the last build.
trigger:
batch: true
branches:
include:
- main
- release/*
paths:
include:
- '*'
exclude:
- eng/Version.Details.xml
- .github/*
- docs/*
- CODE_OF_CONDUCT.md
- CONTRIBUTING.md
- README.md
- SECURITY.md
- LICENSE.TXT
- PATENTS.TXT
- THIRD-PARTY-NOTICES.TXT
pr:
branches:
include:
- main
- release/*
paths:
include:
- '*'
exclude:
- eng/Version.Details.xml
- .github/*
- docs/*
- CODE_OF_CONDUCT.md
- CONTRIBUTING.md
- README.md
- SECURITY.md
- LICENSE.TXT
- PATENTS.TXT
- THIRD-PARTY-NOTICES.TXT
variables:
- name: _TeamName
value: dotnet-r9
- name: NativeToolsOnMachine
value: true
- name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE
value: true
# TEMP until all the x-cutting refactoring is complete
- name: SkipCodeCoverage
value: true
- name: runAsPublic
value: ${{ eq(variables['System.TeamProject'], 'public') }}
- name: _BuildConfig
value: Release
- name: isOfficialBuild
value: ${{ and(ne(variables['runAsPublic'], 'true'), notin(variables['Build.Reason'], 'PullRequest')) }}
- name: IsDeltaBuild
value: ${{ eq(variables['Build.Reason'], 'PullRequest') }}
- name: Build.Arcade.ArtifactsPath
value: $(Build.SourcesDirectory)/artifacts/
- name: Build.Arcade.LogsPath
value: $(Build.Arcade.ArtifactsPath)log/$(_BuildConfig)/
- name: Build.Arcade.TestResultsPath
value: $(Build.Arcade.ArtifactsPath)TestResults/$(_BuildConfig)/
# For full build we can do a shallow build, for a delta build we need the full history.
- ${{ if eq(variables['IsDeltaBuild'], 'true') }}:
- name: _FetchDepth
value: 0
- ${{ else }}:
- name: _FetchDepth
value: 1
- ${{ if or(startswith(variables['Build.SourceBranch'], 'refs/heads/release/'), startswith(variables['Build.SourceBranch'], 'refs/heads/internal/release/'), eq(variables['Build.Reason'], 'Manual')) }}:
- name: PostBuildSign
value: false
- ${{ else }}:
- name: PostBuildSign
value: true
# Produce test-signed build for PR and Public builds
- ${{ if or(eq(variables['runAsPublic'], 'true'), eq(variables['Build.Reason'], 'PullRequest')) }}:
# needed for darc (dependency flow) publishing
- name: _PublishArgs
value: ''
- name: _OfficialBuildIdArgs
value: ''
# needed for signing
- name: _SignType
value: test
- name: _SignArgs
value: ''
- name: _Sign
value: false
# Set up non-PR build from internal project
- ${{ if and(ne(variables['runAsPublic'], 'true'), ne(variables['Build.Reason'], 'PullRequest')) }}:
# needed for darc (dependency flow) publishing
- name: _PublishArgs
value: >-
/p:DotNetPublishUsingPipelines=true
- name: _OfficialBuildIdArgs
value: /p:OfficialBuildId=$(BUILD.BUILDNUMBER)
# needed for signing
- name: _SignType
value: real
- name: _SignArgs
value: /p:DotNetSignType=$(_SignType) /p:TeamName=$(_TeamName) /p:Sign=$(_Sign) /p:DotNetPublishUsingPipelines=true
- name: _Sign
value: true
stages:
- stage: build
displayName: Build
variables:
- template: /eng/common/templates/variables/pool-providers.yml
jobs:
- template: /eng/common/templates/jobs/jobs.yml
parameters:
enableMicrobuild: true
enableTelemetry: true
enableSourceIndex: false
runAsPublic: ${{ variables['runAsPublic'] }}
# Publish build logs
enablePublishBuildArtifacts: true
# Publish test logs
enablePublishTestResults: true
# Publish NuGet packages using v3
# https://github.com/dotnet/arcade/blob/main/Documentation/CorePackages/Publishing.md#basic-onboarding-scenario-for-new-repositories-to-the-current-publishing-version-v3
enablePublishUsingPipelines: true
enablePublishBuildAssets: true
workspace:
clean: all
jobs:
- job: Windows
timeoutInMinutes: 180
testResultsFormat: VSTest
pool:
${{ if eq(variables['runAsPublic'], 'true') }}:
name: $(DncEngPublicBuildPool)
demands: ImageOverride -equals windows.vs2022preview.amd64.open
# Non-public (i.e., official builds)
${{ else }}:
name: $(DncEngInternalBuildPool)
demands: ImageOverride -equals windows.vs2022preview.amd64
variables:
- _buildScript: $(Build.SourcesDirectory)/build.cmd -ci -NativeToolsOnMachine
preSteps:
- checkout: self
clean: true
persistCredentials: true
fetchDepth: $(_FetchDepth)
steps:
- template: \eng\pipelines\templates\BuildAndTest.yml
parameters:
buildScript: $(_buildScript)
buildConfig: $(_BuildConfig)
repoLogPath: $(Build.Arcade.LogsPath)
repoTestResultsPath: $(Build.Arcade.TestResultsPath)
skipCodeCoverage: ${{ eq(variables['SkipCodeCoverage'], 'true') }}
isDeltaBuild: $(IsDeltaBuild)
isWindows: true
warnAsError: 0
- job: Ubuntu
timeoutInMinutes: 180
testResultsFormat: VSTest
pool:
${{ if eq(variables['runAsPublic'], 'true') }}:
name: $(DncEngPublicBuildPool)
demands: ImageOverride -equals build.ubuntu.2004.amd64.open
# Non-public (i.e., official builds)
${{ else }}:
name: $(DncEngInternalBuildPool)
demands: ImageOverride -equals build.ubuntu.2004.amd64
variables:
- _buildScript: $(Build.SourcesDirectory)/build.sh --ci
preSteps:
- checkout: self
clean: true
persistCredentials: true
fetchDepth: $(_FetchDepth)
steps:
- template: \eng\pipelines\templates\BuildAndTest.yml
parameters:
buildScript: $(_buildScript)
buildConfig: $(_BuildConfig)
repoLogPath: $(Build.Arcade.LogsPath)
repoTestResultsPath: $(Build.Arcade.TestResultsPath)
skipCodeCoverage: true
isDeltaBuild: $(IsDeltaBuild)
isWindows: false
warnAsError: 0
- stage: correctness
displayName: Correctness
dependsOn: []
variables:
- template: /eng/common/templates/variables/pool-providers.yml
jobs:
- template: /eng/common/templates/jobs/jobs.yml
parameters:
enableMicrobuild: true
enableTelemetry: true
runAsPublic: ${{ variables['runAsPublic'] }}
workspace:
clean: all
jobs:
- job: WarningsCheck
timeoutInMinutes: 180
pool:
${{ if eq(variables['runAsPublic'], 'true') }}:
name: $(DncEngPublicBuildPool)
demands: ImageOverride -equals build.ubuntu.2004.amd64.open
# Non-public (i.e., official builds)
${{ else }}:
name: $(DncEngInternalBuildPool)
demands: ImageOverride -equals build.ubuntu.2004.amd64
variables:
- _buildScript: $(Build.SourcesDirectory)/build.sh --ci
preSteps:
- checkout: self
clean: true
persistCredentials: true
fetchDepth: $(_FetchDepth)
steps:
- template: \eng\pipelines\templates\BuildAndTest.yml
parameters:
buildScript: $(_buildScript)
buildConfig: $(_BuildConfig)
repoLogPath: $(Build.Arcade.LogsPath)
repoTestResultsPath: $(Build.Arcade.TestResultsPath)
skipCodeCoverage: true
skipTests: true
isDeltaBuild: $(IsDeltaBuild)
isWindows: false
# Publish and validation steps. Only run in official builds
- ${{ if and(ne(variables['runAsPublic'], 'true'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- template: /eng/common/templates/post-build/post-build.yml
parameters:
validateDependsOn:
- build
- correctness
publishingInfraVersion: 3
enableSymbolValidation: false
enableSigningValidation: false
enableNugetValidation: false
enableSourceLinkValidation: false
# these param values come from the DotNet-Winforms-SDLValidation-Params azdo variable group
SDLValidationParameters:
enable: false
params: ' -SourceToolsList $(_TsaSourceToolsList)
-TsaInstanceURL $(_TsaInstanceURL)
-TsaProjectName $(_TsaProjectName)
-TsaNotificationEmail $(_TsaNotificationEmail)
-TsaCodebaseAdmin $(_TsaCodebaseAdmin)
-TsaBugAreaPath $(_TsaBugAreaPath)
-TsaIterationPath $(_TsaIterationPath)
-TsaRepositoryName $(_TsaRepositoryName)
-TsaCodebaseName $(_TsaCodebaseName)
-TsaOnboard $(_TsaOnboard)
-TsaPublish $(_TsaPublish)'

7198
bench/.editorconfig Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,18 @@
<Project>
<PropertyGroup>
<GenerateDocumentationFile Condition="'$(GenerateDocumentationFile)' == ''">false</GenerateDocumentationFile>
</PropertyGroup>
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>$(LatestTargetFramework)</TargetFramework>
<GenerateProgramFile>false</GenerateProgramFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
<Project>
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.targets', '$(MSBuildThisFileDirectory)../'))" />
</Project>

Просмотреть файл

@ -0,0 +1,163 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.EnumStrings;
namespace Microsoft.Gen.EnumStrings.Bench;
#pragma warning disable CA1822 // Mark members as static
#pragma warning disable R9A033 // Replace uses of 'Enum.GetName' and 'Enum.ToString' with the '[EnumStrings]' code generator for improved performance
[MemoryDiagnoser]
public class EnumStrings
{
private static readonly int[] _randomValues = new int[1000];
[EnumStrings]
internal enum Color
{
Red,
Green,
Blue,
}
[Flags]
[EnumStrings]
internal enum SmallOptions
{
Options1 = 1,
Options2 = 2,
Options4 = 4,
Options8 = 8,
Options16 = 16,
}
[Flags]
[EnumStrings]
internal enum LargeOptions
{
Options1 = 1,
Options2 = 2,
Options4 = 4,
Options8 = 8,
Options16 = 16,
Options32 = 32,
Options64 = 64,
Options128 = 128,
}
static EnumStrings()
{
var r = new Random();
for (int i = 0; i < _randomValues.Length; i++)
{
_randomValues[i] = r.Next();
}
}
[Benchmark]
public void ToStringColor()
{
_ = Color.Red.ToString();
_ = Color.Green.ToString();
_ = Color.Blue.ToString();
}
[Benchmark]
public void GetNameColor()
{
_ = Enum.GetName(Color.Red);
_ = Enum.GetName(Color.Green);
_ = Enum.GetName(Color.Blue);
}
[Benchmark]
public void ToInvariantStringColor()
{
_ = Color.Red.ToInvariantString();
_ = Color.Green.ToInvariantString();
_ = Color.Blue.ToInvariantString();
}
[Benchmark]
public void ToStringSmallOptions()
{
_ = SmallOptions.Options1.ToString();
_ = SmallOptions.Options2.ToString();
_ = SmallOptions.Options4.ToString();
_ = SmallOptions.Options8.ToString();
_ = SmallOptions.Options16.ToString();
_ = (SmallOptions.Options1 | SmallOptions.Options16).ToString();
_ = (SmallOptions.Options2 | SmallOptions.Options4).ToString();
}
[Benchmark]
public void ToInvariantStringSmallOptions()
{
_ = SmallOptions.Options1.ToInvariantString();
_ = SmallOptions.Options2.ToInvariantString();
_ = SmallOptions.Options4.ToInvariantString();
_ = SmallOptions.Options8.ToInvariantString();
_ = SmallOptions.Options16.ToInvariantString();
_ = (SmallOptions.Options1 | SmallOptions.Options16).ToInvariantString();
_ = (SmallOptions.Options2 | SmallOptions.Options4).ToInvariantString();
}
[Benchmark]
public void ToStringLargeOptions()
{
_ = LargeOptions.Options1.ToString();
_ = LargeOptions.Options2.ToString();
_ = LargeOptions.Options4.ToString();
_ = LargeOptions.Options8.ToString();
_ = LargeOptions.Options16.ToString();
_ = LargeOptions.Options32.ToString();
_ = LargeOptions.Options64.ToString();
_ = LargeOptions.Options128.ToString();
_ = (LargeOptions.Options1 | LargeOptions.Options16).ToString();
_ = (LargeOptions.Options2 | LargeOptions.Options4).ToString();
}
[Benchmark]
public void ToInvariantStringLargeOptions()
{
_ = LargeOptions.Options1.ToInvariantString();
_ = LargeOptions.Options2.ToInvariantString();
_ = LargeOptions.Options4.ToInvariantString();
_ = LargeOptions.Options8.ToInvariantString();
_ = LargeOptions.Options16.ToInvariantString();
_ = LargeOptions.Options32.ToInvariantString();
_ = LargeOptions.Options64.ToInvariantString();
_ = LargeOptions.Options128.ToInvariantString();
_ = (LargeOptions.Options1 | LargeOptions.Options16).ToInvariantString();
_ = (LargeOptions.Options2 | LargeOptions.Options4).ToInvariantString();
}
// the next two benchmarks aren't representative of expected real-world use cases, but let's see the impact the code gen has relative to naked Enum.ToString
[Benchmark]
public void ToStringRandom()
{
for (int i = 0; i < _randomValues.Length; i++)
{
var o = (LargeOptions)_randomValues[i];
_ = o.ToString();
}
}
[Benchmark]
public void ToInvariantStringRandom()
{
for (int i = 0; i < _randomValues.Length; i++)
{
var o = (LargeOptions)_randomValues[i];
_ = o.ToInvariantString();
}
}
}

Просмотреть файл

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>Microsoft.Gen.EnumStrings.PerformanceTests</RootNamespace>
<Description>Benchmarks for Gen.EnumStrings.</Description>
<UseEnumStringsGenerator>true</UseEnumStringsGenerator>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Libraries\Microsoft.Extensions.EnumStrings\Microsoft.Extensions.EnumStrings.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,21 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Toolchains.InProcess.Emit;
namespace Microsoft.Gen.EnumStrings.Bench;
internal static class Program
{
public static void Main(string[] args)
{
var dontRequireSlnToRunBenchmarks = ManualConfig
.Create(DefaultConfig.Instance)
.AddJob(Job.MediumRun.WithToolchain(InProcessEmitToolchain.Instance));
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, dontRequireSlnToRunBenchmarks);
}
}

Просмотреть файл

@ -0,0 +1,21 @@
```
BenchmarkDotNet=v0.13.2, OS=Windows 11 (10.0.22621.963)
Intel Core i7-9700K CPU 3.60GHz (Coffee Lake), 1 CPU, 8 logical and 8 physical cores
.NET SDK=7.0.100
[Host] : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2
Job=MediumRun Toolchain=InProcessEmitToolchain IterationCount=15
LaunchCount=2 WarmupCount=10
| Method | Mean | Error | StdDev | Gen0 | Allocated |
|------------------------------ |--------------:|--------------:|--------------:|--------:|----------:|
| ToStringColor | 40.991 ns | 0.5249 ns | 0.7358 ns | 0.0114 | 72 B |
| GetNameColor | 33.143 ns | 0.4681 ns | 0.7007 ns | - | - |
| ToInvariantStringColor | 3.834 ns | 0.0178 ns | 0.0267 ns | - | - |
| ToStringSmallOptions | 135.437 ns | 1.7399 ns | 2.5503 ns | 0.0470 | 296 B |
| ToInvariantStringSmallOptions | 12.207 ns | 0.0620 ns | 0.0889 ns | - | - |
| ToStringLargeOptions | 193.580 ns | 2.6614 ns | 3.8169 ns | 0.0587 | 368 B |
| ToInvariantStringLargeOptions | 16.424 ns | 0.2146 ns | 0.3145 ns | - | - |
| ToStringRandom | 72,026.761 ns | 1,205.1409 ns | 1,728.3770 ns | 10.8643 | 68232 B |
| ToInvariantStringRandom | 64,554.832 ns | 581.9061 ns | 852.9504 ns | 8.0566 | 50758 B |
```

Просмотреть файл

@ -0,0 +1,25 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Telemetry.Logging;
#pragma warning disable S109
namespace Microsoft.Gen.Logging.Bench;
internal static partial class Log
{
[LogMethod(LogLevel.Error, @"Connection id '{connectionId}' received {type} frame for stream ID {streamId} with length {length} and flags {flags} and {other}")]
public static partial void RefTypes_Error(ILogger logger, string connectionId, string type, string streamId, string length, string flags, string other);
[LogMethod(LogLevel.Debug, @"Connection id '{connectionId}' received {type} frame for stream ID {streamId} with length {length} and flags {flags} and {other}")]
public static partial void RefTypes_Debug(ILogger logger, string connectionId, string type, string streamId, string length, string flags, string other);
[LogMethod(LogLevel.Error, @"Range [{start}..{end}], options {options}, guid {guid}")]
public static partial void ValueTypes_Error(ILogger logger, long start, long end, int options, Guid guid);
[LogMethod(LogLevel.Debug, @"Range [{start}..{end}], options {options}, guid {guid}")]
public static partial void ValueTypes_Debug(ILogger logger, long start, long end, int options, Guid guid);
}

Просмотреть файл

@ -0,0 +1,109 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.Logging;
#pragma warning disable CA1822 // Mark members as static
#pragma warning disable R9A000 // Switch to updated logging methods using the [LogMethod] attribute for additional performance.
namespace Microsoft.Gen.Logging.Bench;
[MemoryDiagnoser]
public class LogMethod
{
private const string ConnectionId = "0x345334534678";
private const string Type = "some string";
private const string StreamId = "some string some string";
private const string Length = "some string some string some string";
private const string Flags = "some string some string some string some string";
private const string Other = "some string some string some string some string some string";
private const long Start = 42;
private const long End = 123_456_789;
private const int Options = 0x1234;
private static readonly Guid _guid = new(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 });
private static readonly Action<ILogger, string, string, string, string, string, string, Exception?> _loggerMessage_refTypes = LoggerMessage.Define<string, string, string, string, string, string>(
LogLevel.Error,
eventId: 380,
formatString: @"Connection id '{connectionId}' received {type} frame for stream ID {streamId} with length {length} and flags {flags} and {other}");
private static readonly Action<ILogger, long, long, int, Guid, Exception?> _loggerMessage_valueTypes = LoggerMessage.Define<long, long, int, Guid>(
LogLevel.Error,
eventId: 381,
formatString: @"Range [{start}..{end}], options {options}, guid {guid}");
private static readonly MockLogger _logger = new();
[Params(true, false)]
public bool Enabled;
[Benchmark]
public void Classic_RefTypes()
{
_logger.Enabled = Enabled;
_logger.LogError(
@"Connection id '{connectionId}' received {type} frame for stream ID {streamId} with length {length} and flags {flags} and {other}",
ConnectionId,
Type,
StreamId,
Length,
Flags,
Other);
}
[Benchmark]
public void Classic_ValueTypes()
{
_logger.Enabled = Enabled;
_logger.LogError(@"Range [{start}..{end}], options {options}, guid {guid}",
Start,
End,
Options,
_guid);
}
[Benchmark]
public void LoggerMessage_RefTypes()
{
_logger.Enabled = Enabled;
_loggerMessage_refTypes(_logger, ConnectionId, Type, StreamId, Length, Flags, Other, null);
}
[Benchmark]
public void LoggerMessage_ValueTypes()
{
_logger.Enabled = Enabled;
_loggerMessage_valueTypes(_logger, Start, End, Options, _guid, null);
}
[Benchmark]
public void LogMethod_RefTypes_Error()
{
_logger.Enabled = Enabled;
Log.RefTypes_Error(_logger, ConnectionId, Type, StreamId, Length, Flags, Other);
}
[Benchmark]
public void LogMethod_RefTypes_Debug()
{
_logger.Enabled = Enabled;
Log.RefTypes_Debug(_logger, ConnectionId, Type, StreamId, Length, Flags, Other);
}
[Benchmark]
public void LogMethod_ValueTypes_Error()
{
_logger.Enabled = Enabled;
Log.ValueTypes_Error(_logger, Start, End, Options, _guid);
}
[Benchmark]
public void LogMethod_ValueTypes_Debug()
{
_logger.Enabled = Enabled;
Log.ValueTypes_Debug(_logger, Start, End, Options, _guid);
}
}

Просмотреть файл

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>Microsoft.Gen.Logging.Bench</RootNamespace>
<Description>Benchmarks for Gen.Logging.</Description>
<UseLoggingGenerator>true</UseLoggingGenerator>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<InjectSharedPools>true</InjectSharedPools>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Libraries\Microsoft.Extensions.Telemetry.Abstractions\Microsoft.Extensions.Telemetry.Abstractions.csproj " />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,82 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.ObjectPool;
using Microsoft.Extensions.Telemetry.Logging;
using Microsoft.Shared.Pools;
namespace Microsoft.Gen.Logging.Bench;
/// <summary>
/// A logger which captures the last log state logged to it.
/// </summary>
internal sealed class MockLogger : ILogger
{
private readonly ObjectPool<List<KeyValuePair<string, object?>>> _listPool = PoolFactory.CreateListPool<KeyValuePair<string, object?>>();
private sealed class Disposable : IDisposable
{
public void Dispose()
{
// nothing to do
}
}
#pragma warning disable CS8633
#pragma warning disable CS8766
public IDisposable? BeginScope<TState>(TState state)
where TState : notnull
#pragma warning restore CS8633
#pragma warning restore CS8766
{
return new Disposable();
}
public bool IsEnabled(LogLevel logLevel)
{
return Enabled;
}
public bool Enabled { get; set; }
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}
switch (state)
{
case LogMethodHelper helper:
{
// this path is optimized in the real Logger implementation, so it is here too...
break;
}
case IEnumerable<KeyValuePair<string, object?>> enumerable:
{
var l = _listPool.Get();
foreach (var e in enumerable)
{
// Any non-primitive value type will be turned into a string on this path.
// But when using the generated code, this conversion to string happens in the
// generated code, which eliminates the overhead of boxing the value type.
if (e.Value is Guid)
{
_ = e.Value.ToString();
}
l.Add(e);
}
_listPool.Return(l);
break;
}
}
}
}

Просмотреть файл

@ -0,0 +1,21 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Toolchains.InProcess.Emit;
namespace Microsoft.Gen.Logging.Bench;
internal static class Program
{
public static void Main(string[] args)
{
var dontRequireSlnToRunBenchmarks = ManualConfig
.Create(DefaultConfig.Instance)
.AddJob(Job.MediumRun.WithToolchain(InProcessEmitToolchain.Instance));
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, dontRequireSlnToRunBenchmarks);
}
}

Просмотреть файл

@ -0,0 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace Microsoft.AspNetCore.Telemetry;
internal static class Constants
{
public const string AttributeHttpPath = "http.path";
public const string AttributeHttpRoute = "http.route";
public const string AttributeHttpTarget = "http.target";
public const string AttributeHttpUrl = "http.url";
public const string Redacted = "redacted";
public const string CustomPropertyHttpRequest = "Tracing.CustomProperty.HttpRequest";
public const string ActivityStartEvent = "OnStartActivity";
}

Просмотреть файл

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>Microsoft.AspNetCore.Telemetry.Bench</RootNamespace>
<Description>Benchmarks for Microsoft.AspNetCore.Telemetry.</Description>
</PropertyGroup>
<PropertyGroup>
<InjectSharedPools>true</InjectSharedPools>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Libraries\Microsoft.AspNetCore.Telemetry\Microsoft.AspNetCore.Telemetry.csproj" />
<ProjectReference Include="..\..\..\src\Libraries\Microsoft.Extensions.Compliance.Testing\Microsoft.Extensions.Compliance.Testing.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,21 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Toolchains.InProcess.Emit;
namespace Microsoft.AspNetCore.Telemetry.Bench;
internal static class Program
{
public static void Main(string[] args)
{
var dontRequireSlnToRunBenchmarks = ManualConfig
.Create(DefaultConfig.Instance)
.AddJob(Job.MediumRun.WithToolchain(InProcessEmitToolchain.Instance));
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, dontRequireSlnToRunBenchmarks);
}
}

Просмотреть файл

@ -0,0 +1,346 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using System.Text;
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.Compliance.Classification;
using Microsoft.Extensions.Compliance.Testing;
using Microsoft.Extensions.ObjectPool;
using Microsoft.Shared.Pools;
namespace Microsoft.AspNetCore.Telemetry.Bench;
[GcServer(true)]
[MinColumn]
[MaxColumn]
[MemoryDiagnoser]
public class RedactionBenchmark
{
private readonly HttpTracingOptions _options;
private readonly string _httpPath;
private readonly ObjectPool<StringBuilder> _stringBuilderPool;
private readonly Dictionary<string, object?> _routeValues = new()
{
{ "userId", "testUserId" },
{ "chatId", "testChatId" },
};
public RedactionBenchmark()
{
_options = new HttpTracingOptions();
_options.RouteParameterDataClasses.Add("userId", SimpleClassifications.PrivateData);
_options.RouteParameterDataClasses.Add("chatId", SimpleClassifications.PrivateData);
_httpPath = "/users/{userId}/chats/{chatId}/test1/test2/{userId}";
_stringBuilderPool = PoolFactory.CreateStringBuilderPool();
}
private static RouteSegment[] GetRouteSegments(string httpRoute)
{
var routeSegments = new List<RouteSegment>();
int startIndex = 0;
while (startIndex < httpRoute.Length)
{
var startIndexOfParam = httpRoute.IndexOf('{', startIndex);
if (startIndexOfParam == -1)
{
// We have reached to the end of the segment, no more parameters
routeSegments.Add(new RouteSegment(httpRoute.Substring(startIndex), false));
break;
}
var endIndexOfParam = httpRoute.IndexOf('}', startIndexOfParam);
var routeNonParamameterSegment = httpRoute.Substring(startIndex, startIndexOfParam - startIndex);
var routeParameterSegment = httpRoute.Substring(startIndexOfParam + 1, endIndexOfParam - startIndexOfParam - 1);
routeSegments.Add(new RouteSegment(routeNonParamameterSegment, false));
routeSegments.Add(new RouteSegment(routeParameterSegment, true));
startIndex = endIndexOfParam + 1;
}
return routeSegments.ToArray();
}
[Benchmark]
public void RedactHttpPathStringBuilderNETStd()
{
Span<char> destinationBuffer = stackalloc char[256];
var startIndex = 0;
var span = _httpPath.AsSpan();
var isRouteKeyFound = false;
var pathStringBuilder = _stringBuilderPool.Get();
ReadOnlySpan<char> segment;
try
{
for (int i = 0; i <= span.Length; i++)
{
if (i == span.Length || span[i] == '/')
{
segment = span.Slice(startIndex, i - startIndex);
foreach (var item in _routeValues)
{
if (((string)item.Value!).AsSpan().SequenceEqual(segment))
{
if (_options.RouteParameterDataClasses.TryGetValue(item.Key, out DataClassification classification))
{
pathStringBuilder.Append(Redact(segment, destinationBuffer));
isRouteKeyFound = true;
}
break;
}
}
if (!isRouteKeyFound)
{
pathStringBuilder.Append(segment);
}
if (i < span.Length)
{
_ = pathStringBuilder.Append('/');
}
startIndex = i + 1;
isRouteKeyFound = true;
}
}
_ = pathStringBuilder.ToString();
}
finally
{
_stringBuilderPool.Return(pathStringBuilder);
}
}
[Benchmark]
public void RedactHttpPathStringBuilderOptimizedForSpeedNETStd()
{
Span<char> destinationBuffer = stackalloc char[256];
var startIndex = 0;
var span = _httpPath.AsSpan();
var pathStringBuilder = _stringBuilderPool.Get();
var newDict = new Dictionary<string, string>(_routeValues.Count);
foreach (var item in _routeValues)
{
if (item.Value is not null)
{
newDict.Add((string)item.Value, item.Key);
}
}
try
{
for (int i = 0; i <= span.Length; i++)
{
if (i == span.Length || span[i] == '/')
{
var segment = span.Slice(startIndex, i - startIndex).ToString();
if (newDict.TryGetValue(segment, out var value) &&
_options.RouteParameterDataClasses.TryGetValue(value, out DataClassification classification))
{
_ = pathStringBuilder.Append(Redact(segment, destinationBuffer));
}
else
{
_ = pathStringBuilder.Append(segment);
}
if (i < span.Length)
{
_ = pathStringBuilder.Append('/');
}
startIndex = i + 1;
}
}
_ = pathStringBuilder.ToString();
}
finally
{
_stringBuilderPool.Return(pathStringBuilder);
}
}
[Benchmark]
public void RedactHttpPathUsingIndexOfNETStd()
{
Span<char> destinationBuffer = stackalloc char[256];
var span = _httpPath.AsSpan();
var isRouteKeyFound = false;
var pathStringBuilder = _stringBuilderPool.Get();
try
{
var startIndex = 0;
var endIndex = 0;
var segment = span;
while (startIndex < span.Length)
{
_ = pathStringBuilder.Append('/');
startIndex = span.Slice(startIndex).IndexOf('/') + startIndex;
endIndex = span.Slice(startIndex + 1).IndexOf('/') + startIndex;
if (endIndex < startIndex)
{
endIndex = span.Length - 1;
}
segment = span.Slice(startIndex + 1, endIndex - startIndex);
if (segment.Length > 0)
{
foreach (var item in _routeValues)
{
if (((string)item.Value!).AsSpan().SequenceEqual(segment))
{
if (_options.RouteParameterDataClasses.TryGetValue(item.Key, out DataClassification classification))
{
_ = pathStringBuilder.Append(Redact(segment, destinationBuffer));
isRouteKeyFound = true;
}
break;
}
}
if (!isRouteKeyFound)
{
_ = pathStringBuilder.Append(segment);
}
}
startIndex = endIndex + 1;
isRouteKeyFound = false;
}
_ = pathStringBuilder.ToString();
}
finally
{
_stringBuilderPool.Return(pathStringBuilder);
}
}
private static ReadOnlySpan<char> Redact(ReadOnlySpan<char> source, Span<char> destination)
{
return destination.Slice(0, source.Length);
}
private static int[] GetPathSegments(ReadOnlySpan<char> httpPath)
{
var numSegments = 0;
for (var i = 0; i < httpPath.Length; i++)
{
if (httpPath[i] == '/')
{
numSegments++;
}
}
var routeSegments = new int[numSegments + 1];
var j = 0;
for (var i = 0; i < httpPath.Length; i++)
{
if (httpPath[i] == '/')
{
routeSegments[j] = i + 1;
j++;
}
}
routeSegments[numSegments] = httpPath.Length + 1;
return routeSegments;
}
[Benchmark]
public void RedactHttpPathWithSegmentsNETStd()
{
Span<char> destinationBuffer = stackalloc char[256];
var span = _httpPath.AsSpan();
var segments = GetPathSegments(span);
var isRouteKeyFound = false;
var pathStringBuilder = _stringBuilderPool.Get();
try
{
for (int i = 1; i < segments.Length; i++)
{
_ = pathStringBuilder.Append('/');
var segment = span.Slice(segments[i - 1], segments[i] - segments[i - 1] - 1);
foreach (var item in _routeValues)
{
if (((string)item.Value!).AsSpan().SequenceEqual(segment))
{
if (_options.RouteParameterDataClasses.TryGetValue(item.Key, out DataClassification classification))
{
_ = pathStringBuilder.Append(Redact(segment, destinationBuffer));
isRouteKeyFound = true;
}
break;
}
}
if (!isRouteKeyFound)
{
_ = pathStringBuilder.Append(segment);
}
isRouteKeyFound = false;
}
_ = pathStringBuilder.ToString();
}
finally
{
_stringBuilderPool.Return(pathStringBuilder);
}
}
[Benchmark]
public void RedactHttpRouteNETCore()
{
Span<char> destinationBuffer = stackalloc char[256];
var routeSegments = GetRouteSegments(_httpPath);
var pathStringBuilder = _stringBuilderPool.Get();
try
{
foreach (var routeSegment in routeSegments)
{
if (routeSegment.IsParameter)
{
if (_routeValues.TryGetValue(routeSegment.Segment, out var paramValue))
{
if (_options.RouteParameterDataClasses.TryGetValue(routeSegment.Segment, out DataClassification classification))
{
_ = pathStringBuilder.Append(Redact((string)paramValue!, destinationBuffer));
}
else
{
_ = pathStringBuilder.Append(paramValue);
}
}
}
else
{
_ = pathStringBuilder.Append(routeSegment.Segment);
}
}
_ = pathStringBuilder.ToString();
}
finally
{
_stringBuilderPool.Return(pathStringBuilder);
}
}
}

Просмотреть файл

@ -0,0 +1,17 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace Microsoft.AspNetCore.Telemetry;
internal readonly struct RouteSegment
{
public RouteSegment(string segment, bool isParameter)
{
Segment = segment;
IsParameter = isParameter;
}
public string Segment { get; }
public bool IsParameter { get; }
}

Просмотреть файл

@ -0,0 +1,46 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.Extensions.Http.Resilience.Bench;
public class Benchmark
{
private static HttpRequestMessage Request => new(HttpMethod.Post, "https://bogus");
private System.Net.Http.HttpClient _client = null!;
[GlobalSetup]
public void GlobalSetup()
{
var type = RoutingStrategy;
if (ManyRoutes)
{
type |= HedgingClientType.ManyRoutes;
}
var serviceProvider = HttpClientFactory.InitializeServiceProvider(type);
var factory = serviceProvider.GetRequiredService<IHttpClientFactory>();
#pragma warning disable R9A033 // Replace uses of 'Enum.GetName' and 'Enum.ToString' with the '[EnumStrings]' code generator for improved performance
_client = factory.CreateClient(type.ToString());
#pragma warning restore R9A033 // Replace uses of 'Enum.GetName' and 'Enum.ToString' with the '[EnumStrings]' code generator for improved performance
}
[Params(HedgingClientType.Weighted, HedgingClientType.Ordered)]
public HedgingClientType RoutingStrategy { get; set; }
[Params(true, false)]
public bool ManyRoutes { get; set; }
[Benchmark]
public Task<HttpResponseMessage> HedgingCall()
{
return _client.SendAsync(Request, CancellationToken.None);
}
}

Просмотреть файл

@ -0,0 +1,67 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Resilience.FaultInjection;
using Microsoft.Extensions.Telemetry.Metering;
namespace Microsoft.Extensions.Http.Resilience.FaultInjection.PerformanceTests;
public class FaultInjectionRequestBenchmarks
{
private const string HttpClientIdentifier = "HttpClientClass";
private static readonly Uri _defaultUrl = new("https://www.google.ca/");
private ServiceProvider _serviceProvider = null!;
private System.Net.Http.HttpClient _client = null!;
[GlobalSetup]
public void GlobalSetup()
{
var services = new ServiceCollection();
if (SetupFaultInjection)
{
Action<HttpFaultInjectionOptionsBuilder> action = builder =>
builder
.Configure(option =>
{
option.ChaosPolicyOptionsGroups = new Dictionary<string, ChaosPolicyOptionsGroup>();
});
services
.RegisterMetering()
.AddHttpClientFaultInjection(action);
}
services.AddHttpClient(HttpClientIdentifier);
_serviceProvider = services.BuildServiceProvider();
var clientFactory = _serviceProvider.GetRequiredService<IHttpClientFactory>();
_client = clientFactory.CreateClient(HttpClientIdentifier);
}
[GlobalCleanup]
public void GlobalCleanup()
{
_serviceProvider.Dispose();
}
[Params(
true,
false)]
public bool SetupFaultInjection { get; set; }
[Benchmark]
public async Task SendAsync()
{
using var request = new HttpRequestMessage(HttpMethod.Get, _defaultUrl);
await _client.SendAsync(request, HttpCompletionOption.ResponseContentRead, CancellationToken.None).ConfigureAwait(false);
}
}

Просмотреть файл

@ -0,0 +1,99 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.Extensions.Compliance.Redaction;
using Microsoft.Extensions.Compliance.Testing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Telemetry.Metering;
#pragma warning disable R9A033 // Replace uses of 'Enum.GetName' and 'Enum.ToString' with the '[EnumStrings]' code generator for improved performance
namespace Microsoft.Extensions.Http.Resilience.Bench;
[Flags]
[SuppressMessage("Performance", "R9A031:Make types declared in an executable internal", Justification = "Needs to be public for BenchmarkDotNet consumption")]
public enum HedgingClientType
{
Weighted = 1 << 0,
Ordered = 1 << 1,
ManyRoutes = 1 << 2,
}
internal static class HttpClientFactory
{
private const string HedgingEndpoint1 = "http://localhost1";
private const string HedgingEndpoint2 = "http://localhost2";
public static ServiceProvider InitializeServiceProvider(HedgingClientType clientType)
{
var services = new ServiceCollection();
services
.RegisterMetering()
.AddSingleton<IRedactorProvider>(NullRedactorProvider.Instance)
.AddTransient<NoRemoteCallHandler>()
.AddHedging(clientType);
return services.BuildServiceProvider();
}
private static IServiceCollection AddHedging(this IServiceCollection services, HedgingClientType clientType)
{
var clientBuilder = services.AddHttpClient(clientType.ToString());
var hedgingBuilder = clientBuilder.AddStandardHedgingHandler().SelectPipelineByAuthority(SimpleClassifications.PublicData);
_ = clientBuilder.AddHttpMessageHandler<NoRemoteCallHandler>();
int routes = clientType.HasFlag(HedgingClientType.ManyRoutes) ? 50 : 2;
if (clientType.HasFlag(HedgingClientType.Ordered))
{
hedgingBuilder.RoutingStrategyBuilder.ConfigureOrderedGroups(options =>
{
options.Groups = Enumerable.Repeat(0, routes).Select(_ =>
{
return new EndpointGroup
{
Endpoints = new[]
{
new WeightedEndpoint
{
Uri = new Uri(HedgingEndpoint1)
},
new WeightedEndpoint
{
Uri = new Uri(HedgingEndpoint2)
}
}
};
}).ToArray();
});
}
else
{
hedgingBuilder.RoutingStrategyBuilder.ConfigureWeightedGroups(options =>
{
options.Groups = Enumerable.Repeat(0, routes).Select(_ =>
{
return new WeightedEndpointGroup
{
Endpoints = new[]
{
new WeightedEndpoint
{
Uri = new Uri(HedgingEndpoint1)
},
new WeightedEndpoint
{
Uri = new Uri(HedgingEndpoint2)
}
}
};
}).ToArray();
});
}
return services;
}
}

Просмотреть файл

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>Microsoft.Extensions.Http.Resilience.FaultInjection.PerformanceTests</RootNamespace>
<Description>Benchmarks for Microsoft.Extensions.Http.Resilience.</Description>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Libraries\Microsoft.Extensions.Http.Resilience\Microsoft.Extensions.Http.Resilience.csproj" />
<ProjectReference Include="..\..\..\src\Libraries\Microsoft.Extensions.Telemetry.Abstractions\Microsoft.Extensions.Telemetry.Abstractions.csproj" />
<ProjectReference Include="..\..\..\src\Libraries\Microsoft.Extensions.Compliance.Testing\Microsoft.Extensions.Compliance.Testing.csproj" />
<ProjectReference Include="..\..\..\src\Libraries\Microsoft.Extensions.Compliance.Redaction\Microsoft.Extensions.Compliance.Redaction.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,28 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.Extensions.Http.Resilience.Bench;
internal sealed class NoRemoteCallHandler : DelegatingHandler
{
private readonly Task<HttpResponseMessage> _completedResponse;
public NoRemoteCallHandler()
{
_completedResponse = Task.FromResult(new HttpResponseMessage
{
StatusCode = System.Net.HttpStatusCode.OK
});
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
#pragma warning disable VSTHRD003 // Avoid awaiting foreign Tasks
return _completedResponse;
#pragma warning restore VSTHRD003 // Avoid awaiting foreign Tasks
}
}

Просмотреть файл

@ -0,0 +1,24 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Toolchains.InProcess.Emit;
namespace Microsoft.Extensions.Http.Resilience.FaultInjection.Benchmark
{
internal static class Program
{
private static void Main(string[] args)
{
var doNotRequireSlnToRunBenchmarks = ManualConfig
.Create(DefaultConfig.Instance)
.AddJob(Job.MediumRun.WithToolchain(InProcessEmitToolchain.Instance).WithIterationCount(100))
.AddDiagnoser(MemoryDiagnoser.Default);
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, doNotRequireSlnToRunBenchmarks);
}
}
}

Просмотреть файл

@ -0,0 +1,22 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Net.Http;
using Microsoft.Extensions.Telemetry.Enrichment;
namespace Microsoft.Extensions.Http.Telemetry.Logging.Bench;
internal sealed class BenchEnricher : IHttpClientLogEnricher
{
private const string Key = "Performance in R9";
private const string Value = "is paramount.";
public void Enrich(IEnrichmentPropertyBag enrichmentBag, HttpRequestMessage? request = null,
HttpResponseMessage? response = null)
{
if (request is not null)
{
enrichmentBag.Add(Key, Value);
}
}
}

Просмотреть файл

@ -0,0 +1,202 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics.CodeAnalysis;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
namespace Microsoft.Extensions.Http.Telemetry.Logging.Bench.Benchmarks;
[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Bench")]
public class HugeHttpClientLoggingBenchmark
{
private const string DataFileName = "HugeBody.txt";
private const int ReadSizeLimit = 53248;
private static HttpRequestMessage Request => new(HttpMethod.Post, "https://www.microsoft.com");
private static readonly System.Net.Http.HttpClient _hugeNoLog
= HttpClientFactory.CreateWithoutLogging(DataFileName);
private static readonly System.Net.Http.HttpClient _hugeLogAll
= HttpClientFactory.CreateWithLoggingLogAll(DataFileName, ReadSizeLimit);
private static readonly System.Net.Http.HttpClient _hugeLogRequest
= HttpClientFactory.CreateWithLoggingLogRequest(DataFileName, ReadSizeLimit);
private static readonly System.Net.Http.HttpClient _hugeLogResponse
= HttpClientFactory.CreateWithLoggingLogResponse(DataFileName, ReadSizeLimit);
private static readonly System.Net.Http.HttpClient _hugeNoLogChunked
= HttpClientFactory.CreateWithoutLogging_ChunkedEncoding(DataFileName);
private static readonly System.Net.Http.HttpClient _hugeLogAllChunked
= HttpClientFactory.CreateWithLoggingLogAll_ChunkedEncoding(DataFileName, ReadSizeLimit);
private static readonly System.Net.Http.HttpClient _hugeLogRequestChunked
= HttpClientFactory.CreateWithLoggingLogRequest_ChunkedEncoding(DataFileName, ReadSizeLimit);
private static readonly System.Net.Http.HttpClient _hugeLogResponseChunked
= HttpClientFactory.CreateWithLoggingLogResponse_ChunkedEncoding(DataFileName, ReadSizeLimit);
[Benchmark(Baseline = true)]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Huge_No_Log_HeadersRead()
{
var response = await _hugeNoLog.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Huge_No_Log_ContentRead()
{
var response = await _hugeNoLog.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Huge_Log_All_HeadersRead()
{
var response = await _hugeLogAll.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Huge_Log_All_ContentRead()
{
var response = await _hugeLogAll.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Huge_Log_Request_HeadersRead()
{
var response = await _hugeLogRequest.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Huge_Log_Request_ContentRead()
{
var response = await _hugeLogRequest.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Huge_Log_Response_HeadersRead()
{
var response = await _hugeLogResponse.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Huge_Log_Response_ContentRead()
{
var response = await _hugeLogResponse.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Huge_No_Log_HeadersRead_ChunkedEncoding()
{
var response = await _hugeNoLogChunked.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Huge_No_Log_ContentRead_ChunkedEncoding()
{
var response = await _hugeNoLogChunked.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Huge_Log_All_HeadersRead_ChunkedEncoding()
{
var response = await _hugeLogAllChunked.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Huge_Log_All_ContentRead_ChunkedEncoding()
{
var response = await _hugeLogAllChunked.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Huge_Log_Request_HeadersRead_ChunkedEncoding()
{
var response = await _hugeLogRequestChunked.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Huge_Log_Request_ContentRead_ChunkedEncoding()
{
var response = await _hugeLogRequestChunked.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Huge_Log_Response_HeadersRead_ChunkedEncoding()
{
var response = await _hugeLogResponseChunked.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Huge_Log_Response_ContentRead_ChunkedEncoding()
{
var response = await _hugeLogResponseChunked.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
}

Просмотреть файл

@ -0,0 +1,202 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics.CodeAnalysis;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
namespace Microsoft.Extensions.Http.Telemetry.Logging.Bench.Benchmarks;
[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Bench")]
public class MediumHttpClientLoggingBenchmark
{
private const string DataFileName = "MediumBody.txt";
private const int ReadSizeLimit = 16384;
private static HttpRequestMessage Request => new(HttpMethod.Post, "https://www.microsoft.com");
private static readonly System.Net.Http.HttpClient _mediumNoLog
= HttpClientFactory.CreateWithoutLogging(DataFileName);
private static readonly System.Net.Http.HttpClient _mediumLogAll
= HttpClientFactory.CreateWithLoggingLogAll(DataFileName, ReadSizeLimit);
private static readonly System.Net.Http.HttpClient _mediumLogRequest
= HttpClientFactory.CreateWithLoggingLogRequest(DataFileName, ReadSizeLimit);
private static readonly System.Net.Http.HttpClient _mediumLogResponse
= HttpClientFactory.CreateWithLoggingLogResponse(DataFileName, ReadSizeLimit);
private static readonly System.Net.Http.HttpClient _mediumNoLogChunked
= HttpClientFactory.CreateWithoutLogging_ChunkedEncoding(DataFileName);
private static readonly System.Net.Http.HttpClient _mediumLogAllChunked
= HttpClientFactory.CreateWithLoggingLogAll_ChunkedEncoding(DataFileName, ReadSizeLimit);
private static readonly System.Net.Http.HttpClient _mediumLogRequestChunked
= HttpClientFactory.CreateWithLoggingLogRequest_ChunkedEncoding(DataFileName, ReadSizeLimit);
private static readonly System.Net.Http.HttpClient _mediumLogResponseChunked
= HttpClientFactory.CreateWithLoggingLogResponse_ChunkedEncoding(DataFileName, ReadSizeLimit);
[Benchmark(Baseline = true)]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Medium_No_Log_HeadersRead()
{
var response = await _mediumNoLog.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Medium_No_Log_ContentRead()
{
var response = await _mediumNoLog.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Medium_Log_All_HeadersRead()
{
var response = await _mediumLogAll.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Medium_Log_All_ContentRead()
{
var response = await _mediumLogAll.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Medium_Log_Request_HeadersRead()
{
var response = await _mediumLogRequest.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Medium_Log_Request_ContentRead()
{
var response = await _mediumLogRequest.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Medium_Log_Response_HeadersRead()
{
var response = await _mediumLogResponse.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Medium_Log_Response_ContentRead()
{
var response = await _mediumLogResponse.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Medium_No_Log_HeadersRead_ChunkedEncoding()
{
var response = await _mediumNoLogChunked.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Medium_No_Log_ContentRead_ChunkedEncoding()
{
var response = await _mediumNoLogChunked.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Medium_Log_All_HeadersRead_ChunkedEncoding()
{
var response = await _mediumLogAllChunked.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Medium_Log_All_ContentRead_ChunkedEncoding()
{
var response = await _mediumLogAllChunked.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Medium_Log_Request_HeadersRead_ChunkedEncoding()
{
var response = await _mediumLogRequestChunked.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Medium_Log_Request_ContentRead_ChunkedEncoding()
{
var response = await _mediumLogRequestChunked.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Medium_Log_Response_HeadersRead_ChunkedEncoding()
{
var response = await _mediumLogResponseChunked.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Medium_Log_Response_ContentRead_ChunkedEncoding()
{
var response = await _mediumLogResponseChunked.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
}

Просмотреть файл

@ -0,0 +1,202 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics.CodeAnalysis;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
namespace Microsoft.Extensions.Http.Telemetry.Logging.Bench.Benchmarks;
[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Bench")]
public class SmallHttpClientLoggingBenchmark
{
private const string DataFileName = "SmallBody.txt";
private const int ReadSizeLimit = 8192;
private static HttpRequestMessage Request => new(HttpMethod.Post, "https://www.microsoft.com");
private static readonly System.Net.Http.HttpClient _smallNoLog
= HttpClientFactory.CreateWithoutLogging(DataFileName);
private static readonly System.Net.Http.HttpClient _smallLogAll
= HttpClientFactory.CreateWithLoggingLogAll(DataFileName, ReadSizeLimit);
private static readonly System.Net.Http.HttpClient _smallLogRequest
= HttpClientFactory.CreateWithLoggingLogRequest(DataFileName, ReadSizeLimit);
private static readonly System.Net.Http.HttpClient _smallLogResponse
= HttpClientFactory.CreateWithLoggingLogResponse(DataFileName, ReadSizeLimit);
private static readonly System.Net.Http.HttpClient _smallNoLogChunked
= HttpClientFactory.CreateWithoutLogging_ChunkedEncoding(DataFileName);
private static readonly System.Net.Http.HttpClient _smallLogAllChunked
= HttpClientFactory.CreateWithLoggingLogAll_ChunkedEncoding(DataFileName, ReadSizeLimit);
private static readonly System.Net.Http.HttpClient _smallLogRequestChunked
= HttpClientFactory.CreateWithLoggingLogRequest_ChunkedEncoding(DataFileName, ReadSizeLimit);
private static readonly System.Net.Http.HttpClient _smallLogResponseChunked
= HttpClientFactory.CreateWithLoggingLogResponse_ChunkedEncoding(DataFileName, ReadSizeLimit);
[Benchmark(Baseline = true)]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Small_No_Log_HeadersRead()
{
var response = await _smallNoLog.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Small_No_Log_ContentRead()
{
var response = await _smallNoLog.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Small_Log_All_HeadersRead()
{
var response = await _smallLogAll.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Small_Log_All_ContentRead()
{
var response = await _smallLogAll.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Small_Log_Request_HeadersRead()
{
var response = await _smallLogRequest.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Small_Log_Request_ContentRead()
{
var response = await _smallLogRequest.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Small_Log_Response_HeadersRead()
{
var response = await _smallLogResponse.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("Seekable")]
public async Task<HttpResponseMessage> Small_Log_Response_ContentRead()
{
var response = await _smallLogResponse.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Small_No_Log_HeadersRead_ChunkedEncoding()
{
var response = await _smallNoLogChunked.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Small_No_Log_ContentRead_ChunkedEncoding()
{
var response = await _smallNoLogChunked.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Small_Log_All_HeadersRead_ChunkedEncoding()
{
var response = await _smallLogAllChunked.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Small_Log_All_ContentRead_ChunkedEncoding()
{
var response = await _smallLogAllChunked.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Small_Log_Request_HeadersRead_ChunkedEncoding()
{
var response = await _smallLogRequestChunked.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Small_Log_Request_ContentRead_ChunkedEncoding()
{
var response = await _smallLogRequestChunked.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Small_Log_Response_HeadersRead_ChunkedEncoding()
{
var response = await _smallLogResponseChunked.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
[Benchmark]
[BenchmarkCategory("NonSeekable")]
public async Task<HttpResponseMessage> Small_Log_Response_ContentRead_ChunkedEncoding()
{
var response = await _smallLogResponseChunked.SendAsync(Request, HttpCompletionOption.ResponseContentRead, CancellationToken.None)
.ConfigureAwait(false);
return response;
}
}

Просмотреть файл

@ -0,0 +1,29 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using Microsoft.Extensions.Logging;
namespace Microsoft.Extensions.Http.Telemetry.Logging.Bench;
internal sealed class DropMessageLogger : ILogger
{
internal static readonly Func<LogLevel, EventId, object, Exception, object?> CreateLogRecord
= (_, _, _, _) => null;
#pragma warning disable CS8633
#pragma warning disable CS8766
public IDisposable? BeginScope<TState>(TState state)
where TState : notnull => null;
#pragma warning restore CS8633
#pragma warning restore CS8766
public bool IsEnabled(LogLevel logLevel) => true;
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
#pragma warning disable CS8604 // Possible null reference argument.
_ = CreateLogRecord(logLevel, eventId, state, exception);
#pragma warning restore CS8604 // Possible null reference argument.
}
}

Просмотреть файл

@ -0,0 +1,18 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics.CodeAnalysis;
using Microsoft.Extensions.Logging;
namespace Microsoft.Extensions.Http.Telemetry.Logging.Bench;
internal sealed class DropMessageLoggerProvider : ILoggerProvider
{
public ILogger CreateLogger(string categoryName) => new DropMessageLogger();
[SuppressMessage("Critical Code Smell", "S1186:Methods should not be empty",
Justification = "Noop")]
public void Dispose()
{
}
}

Просмотреть файл

@ -0,0 +1,180 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Net.Http;
using Microsoft.Extensions.Compliance.Testing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
namespace Microsoft.Extensions.Http.Telemetry.Logging.Bench;
internal static class HttpClientFactory
{
public static System.Net.Http.HttpClient CreateWithLoggingLogRequest(string fileName, int readLimit)
{
var services = new ServiceCollection();
services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, DropMessageLoggerProvider>());
return services
.AddFakeRedaction()
.AddSingleton(_ => NoRemoteCallHandler.Create(fileName))
.AddHttpClientLogEnricher<BenchEnricher>()
.AddHttpClient(nameof(fileName))
.AddHttpClientLogging(options =>
{
options.BodySizeLimit = readLimit;
options.RequestBodyContentTypes.Add(new("application/json"));
options.RequestHeadersDataClasses.Add("Content-Type", SimpleClassifications.PrivateData);
})
.AddHttpMessageHandler<NoRemoteCallHandler>()
.Services
.BuildServiceProvider()
.GetRequiredService<IHttpClientFactory>()
.CreateClient(nameof(fileName));
}
public static System.Net.Http.HttpClient CreateWithLoggingLogResponse(string fileName, int readLimit)
{
var services = new ServiceCollection();
services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, DropMessageLoggerProvider>());
return services
.AddFakeRedaction()
.AddSingleton(_ => NoRemoteCallHandler.Create(fileName))
.AddHttpClient(nameof(fileName))
.AddHttpClientLogging(options =>
{
options.BodySizeLimit = readLimit;
options.ResponseBodyContentTypes.Add(new("application/json"));
options.ResponseHeadersDataClasses.Add("Content-Type", SimpleClassifications.PrivateData);
})
.AddHttpMessageHandler<NoRemoteCallHandler>()
.Services
.BuildServiceProvider()
.GetRequiredService<IHttpClientFactory>()
.CreateClient(nameof(fileName));
}
public static System.Net.Http.HttpClient CreateWithLoggingLogAll(string fileName, int readLimit)
{
var services = new ServiceCollection();
services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, DropMessageLoggerProvider>());
return services
.AddFakeRedaction()
.AddSingleton(_ => NoRemoteCallHandler.Create(fileName))
.AddHttpClient(nameof(fileName))
.AddHttpClientLogging(options =>
{
options.BodySizeLimit = readLimit;
options.RequestBodyContentTypes.Add(new("application/json"));
options.RequestHeadersDataClasses.Add("Content-Type", SimpleClassifications.PrivateData);
options.ResponseBodyContentTypes.Add(new("application/json"));
options.ResponseHeadersDataClasses.Add("Content-Type", SimpleClassifications.PrivateData);
})
.AddHttpMessageHandler<NoRemoteCallHandler>()
.Services
.BuildServiceProvider()
.GetRequiredService<IHttpClientFactory>()
.CreateClient(nameof(fileName));
}
public static System.Net.Http.HttpClient CreateWithLoggingLogRequest_ChunkedEncoding(string fileName, int readLimit)
{
var services = new ServiceCollection();
services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, DropMessageLoggerProvider>());
return services
.AddFakeRedaction()
.AddSingleton(_ => NoRemoteCallNotSeekableHandler.Create(fileName))
.AddHttpClient(nameof(fileName))
.AddHttpClientLogging(options =>
{
options.BodySizeLimit = readLimit;
options.RequestBodyContentTypes.Add("application/json");
options.RequestHeadersDataClasses.Add("Content-Type", SimpleClassifications.PrivateData);
})
.AddHttpMessageHandler<NoRemoteCallNotSeekableHandler>()
.Services
.BuildServiceProvider()
.GetRequiredService<IHttpClientFactory>()
.CreateClient(nameof(fileName));
}
public static System.Net.Http.HttpClient CreateWithLoggingLogResponse_ChunkedEncoding(string fileName, int readLimit)
{
var services = new ServiceCollection();
services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, DropMessageLoggerProvider>());
return services
.AddFakeRedaction()
.AddSingleton(_ => NoRemoteCallNotSeekableHandler.Create(fileName))
.AddHttpClient(nameof(fileName))
.AddHttpClientLogging(options =>
{
options.BodySizeLimit = readLimit;
options.ResponseBodyContentTypes.Add("application/json");
options.ResponseHeadersDataClasses.Add("Content-Type", SimpleClassifications.PrivateData);
})
.AddHttpMessageHandler<NoRemoteCallNotSeekableHandler>()
.Services
.BuildServiceProvider()
.GetRequiredService<IHttpClientFactory>()
.CreateClient(nameof(fileName));
}
public static System.Net.Http.HttpClient CreateWithLoggingLogAll_ChunkedEncoding(string fileName, int readLimit)
{
var services = new ServiceCollection();
services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, DropMessageLoggerProvider>());
return services
.AddFakeRedaction()
.AddSingleton(_ => NoRemoteCallNotSeekableHandler.Create(fileName))
.AddHttpClient(nameof(fileName))
.AddHttpClientLogging(options =>
{
options.BodySizeLimit = readLimit;
options.RequestBodyContentTypes.Add("application/json");
options.RequestHeadersDataClasses.Add("Content-Type", SimpleClassifications.PrivateData);
options.ResponseBodyContentTypes.Add("application/json");
options.ResponseHeadersDataClasses.Add("Content-Type", SimpleClassifications.PrivateData);
})
.AddHttpMessageHandler<NoRemoteCallNotSeekableHandler>()
.Services
.BuildServiceProvider()
.GetRequiredService<IHttpClientFactory>()
.CreateClient(nameof(fileName));
}
public static System.Net.Http.HttpClient CreateWithoutLogging(string fileName)
=> new ServiceCollection()
.AddSingleton(_ => NoRemoteCallHandler.Create(fileName))
.AddHttpClient(nameof(fileName))
.AddHttpMessageHandler<NoRemoteCallHandler>()
.Services
.BuildServiceProvider()
.GetRequiredService<IHttpClientFactory>()
.CreateClient(nameof(fileName));
public static System.Net.Http.HttpClient CreateWithoutLogging_ChunkedEncoding(string fileName)
=> new ServiceCollection()
.AddSingleton(_ => NoRemoteCallNotSeekableHandler.Create(fileName))
.AddHttpClient(nameof(fileName))
.AddHttpMessageHandler<NoRemoteCallNotSeekableHandler>()
.Services
.BuildServiceProvider()
.GetRequiredService<IHttpClientFactory>()
.CreateClient(nameof(fileName));
}

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>Microsoft.Extensions.Http.Telemetry.Logging.Bench</RootNamespace>
<Description>Benchmarks for Microsoft.Extensions.Http.Telemetry.PerformanceTests.</Description>
</PropertyGroup>
<ItemGroup>
<None Update="HugeBody.txt" CopyToOutputDirectory="PreserveNewest" />
<None Update="MediumBody.txt" CopyToOutputDirectory="PreserveNewest" />
<None Update="SmallBody.txt" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Libraries\Microsoft.Extensions.Http.Telemetry\Microsoft.Extensions.Http.Telemetry.csproj" />
<ProjectReference Include="..\..\..\src\Libraries\Microsoft.Extensions.Compliance.Testing\Microsoft.Extensions.Compliance.Testing.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,53 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.Extensions.Http.Telemetry.Logging.Bench;
internal sealed class NoRemoteCallHandler : DelegatingHandler
{
private readonly byte[] _data;
private NoRemoteCallHandler(byte[] data)
{
_data = data;
}
[SuppressMessage("Performance", "R9A017:Switch to an asynchronous method for increased performance.",
Justification = "No async overload for `Directory.GetFiles`.")]
[SuppressMessage("Performance Analysis", "CPR120:File.ReadAllXXX should be replaced by using a StreamReader to avoid adding objects to the large object heap (LOH).",
Justification = "We can live with it here")]
public static NoRemoteCallHandler Create(string fileName)
{
var assemblyFileLocation = Path.GetDirectoryName(typeof(NoRemoteCallHandler).Assembly.Location)!;
var uri = new Uri(assemblyFileLocation).LocalPath;
var responseFilePath = Path.Combine(Directory.GetFiles(
path: uri,
searchPattern: fileName));
var fileContent = File.ReadAllBytes(responseFilePath);
return new NoRemoteCallHandler(fileContent);
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var response = new HttpResponseMessage
{
StatusCode = System.Net.HttpStatusCode.OK,
RequestMessage = request,
Content = new StreamContent(new MemoryStream(_data))
};
response.Content.Headers.ContentType = new("application/json");
return Task.FromResult(response);
}
}

Просмотреть файл

@ -0,0 +1,53 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.Extensions.Http.Telemetry.Logging.Bench;
internal sealed class NoRemoteCallNotSeekableHandler : DelegatingHandler
{
private readonly byte[] _data;
private NoRemoteCallNotSeekableHandler(byte[] data)
{
_data = data;
}
[SuppressMessage("Performance", "R9A017:Switch to an asynchronous method for increased performance.",
Justification = "No async overload for `Directory.GetFiles`.")]
[SuppressMessage("Performance Analysis", "CPR120:File.ReadAllXXX should be replaced by using a StreamReader to avoid adding objects to the large object heap (LOH).",
Justification = "We can live with it here")]
public static NoRemoteCallNotSeekableHandler Create(string fileName)
{
var assemblyFileLocation = Path.GetDirectoryName(typeof(NoRemoteCallHandler).Assembly.Location)!;
var uri = new Uri(assemblyFileLocation).LocalPath;
var responseFilePath = Path.Combine(Directory.GetFiles(
path: uri,
searchPattern: fileName));
var fileContent = File.ReadAllBytes(responseFilePath);
return new NoRemoteCallNotSeekableHandler(fileContent);
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var response = new HttpResponseMessage
{
StatusCode = System.Net.HttpStatusCode.OK,
RequestMessage = request,
Content = new StreamContent(new NotSeekableStream(new MemoryStream(_data)))
};
response.Content.Headers.ContentType = new("application/json");
return Task.FromResult(response);
}
}

Просмотреть файл

@ -0,0 +1,47 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.Extensions.Http.Telemetry.Logging.Bench;
internal sealed class NotSeekableStream : Stream
{
private readonly MemoryStream _innerStream;
public NotSeekableStream(MemoryStream memoryStream)
{
_innerStream = memoryStream;
}
public override bool CanRead => true;
public override bool CanSeek => false;
public override bool CanWrite => true;
public override long Length => _innerStream.Length;
public override long Position { get => _innerStream.Position; set => throw new NotSupportedException("This is not a seekable stream."); }
public override void Flush() => _innerStream.Flush();
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) => _innerStream.ReadAsync(buffer, offset, count, cancellationToken);
public override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default) => _innerStream.ReadAsync(buffer, cancellationToken);
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) => _innerStream.WriteAsync(buffer, offset, count, cancellationToken);
public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default) => _innerStream.WriteAsync(buffer, cancellationToken);
public override int Read(byte[] buffer, int offset, int count) => _innerStream.Read(buffer, offset, count);
public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException("This is not a seekable stream.");
public override void SetLength(long value) => _innerStream.SetLength(value);
public override void Write(byte[] buffer, int offset, int count) => _innerStream.Write(buffer, offset, count);
}

Просмотреть файл

@ -0,0 +1,31 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Environments;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Order;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Toolchains.InProcess.Emit;
namespace Microsoft.Extensions.Http.Telemetry.Logging.Bench;
internal static class Program
{
private static void Main(string[] args)
{
var dontRequireSlnToRunBenchmarks = ManualConfig
.Create(DefaultConfig.Instance)
.AddJob(Job.MediumRun
.WithRuntime(CoreRuntime.Core50)
.WithGcServer(true)
.WithJit(Jit.RyuJit)
.WithPlatform(Platform.X64)
.WithToolchain(InProcessEmitToolchain.Instance))
.WithOrderer(new DefaultOrderer(SummaryOrderPolicy.FastestToSlowest, MethodOrderPolicy.Declared))
.AddDiagnoser(MemoryDiagnoser.Default);
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, dontRequireSlnToRunBenchmarks);
}
}

Просмотреть файл

@ -0,0 +1,145 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Diagnostics;
using System.Net.Http;
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.Compliance.Classification;
using Microsoft.Extensions.Compliance.Redaction;
using Microsoft.Extensions.Compliance.Testing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Telemetry;
using Microsoft.Extensions.Telemetry.Internal;
namespace Microsoft.Extensions.Http.Telemetry.Tracing.Bench;
#pragma warning disable S1075 // URIs should not be hardcoded
#pragma warning disable SA1203 // Constants should appear before fields
[GcServer(true)]
[MinColumn]
[MaxColumn]
[MemoryDiagnoser]
#pragma warning disable CA1063 // Implement IDisposable Correctly
public class RedactionProcessorBench : IDisposable
#pragma warning restore CA1063 // Implement IDisposable Correctly
{
private const string ShortPath = "http://test.com/api/routes/routeId123/chats/chatId123/routeId123/chats/chatId123";
private const string ShortRoute = "/api/routes/{routeId}/chats/{chatId}/{routeId}/chats/{chatId}";
private HttpClientRedactionProcessor? _shortRedactionProcessor;
private Activity? _shortAcivity;
private HttpRequestMessage? _shortMessage;
private const string LongPath
= "http://test.com/api/something/something/something/something/something/FJWIEFNJIWEFJI/FJWIEFNJIWEFJI/something/FJWIEFNJIWEFJI/FJWIEFNJIWEFJI/routes/route123/users/user232/chats/chatr213";
private const string LongRoute = "/api/something/something/something/something/something/{blabla}/{blabla}/something/{blabla}/{blabla}/routes/{routeId}/users/{userId}/chats/{chatId}";
private HttpClientRedactionProcessor? _longRedactionProcessor;
private Activity? _longAcivity;
private HttpRequestMessage? _longMessage;
[GlobalSetup]
public void Setup()
{
var builder = new ServiceCollection()
.AddFakeRedaction(options => options.RedactionFormat = "Redacted:{0}")
.AddHttpRouteProcessor()
.AddOutgoingRequestContext()
.BuildServiceProvider();
IRedactorProvider redactorProvider = new RP();
IHttpPathRedactor httpPathRedactor = builder.GetService<IHttpPathRedactor>()!;
var requestMetadataContext = builder.GetService<IOutgoingRequestContext>()!;
var options = new HttpClientTracingOptions();
options.RouteParameterDataClasses.Add("routeId", SimpleClassifications.PrivateData);
options.RouteParameterDataClasses.Add("chatId", SimpleClassifications.PrivateData);
options.RouteParameterDataClasses.Add("userId", SimpleClassifications.PrivateData);
_shortRedactionProcessor = new HttpClientRedactionProcessor(
Microsoft.Extensions.Options.Options.Create(options),
httpPathRedactor,
requestMetadataContext);
_shortAcivity = new Activity("short_activity");
_shortMessage = new()
{
RequestUri = new Uri(ShortPath)
};
_shortMessage.SetRequestMetadata(new RequestMetadata { RequestRoute = ShortRoute });
_shortAcivity.SetCustomProperty(Constants.CustomPropertyHttpRequestMessage, _shortMessage);
var longOptions = new HttpClientTracingOptions();
longOptions.RouteParameterDataClasses.Add("routeId", SimpleClassifications.PrivateData);
longOptions.RouteParameterDataClasses.Add("chatId", SimpleClassifications.PrivateData);
longOptions.RouteParameterDataClasses.Add("userId", SimpleClassifications.PrivateData);
longOptions.RouteParameterDataClasses.Add("blabla", SimpleClassifications.PrivateData);
_longRedactionProcessor = new HttpClientRedactionProcessor(
Microsoft.Extensions.Options.Options.Create(longOptions),
httpPathRedactor,
requestMetadataContext);
_longAcivity = new Activity("long_activity");
_longMessage = new()
{
RequestUri = new Uri(LongPath)
};
_longMessage.SetRequestMetadata(new RequestMetadata { RequestRoute = LongRoute });
_longAcivity.SetCustomProperty(Constants.CustomPropertyHttpRequestMessage, _longMessage);
}
[Benchmark]
public int Short_Uri_Processing()
{
_shortRedactionProcessor!.Process(_shortAcivity!, _shortMessage!);
return 0;
}
[Benchmark]
public int Long_Uri_Processing()
{
_longRedactionProcessor!.Process(_longAcivity!, _longMessage!);
return 0;
}
#pragma warning disable CA1063 // Implement IDisposable Correctly
#pragma warning disable CA1816 // Dispose methods should call SuppressFinalize
public void Dispose()
#pragma warning restore CA1816 // Dispose methods should call SuppressFinalize
#pragma warning restore CA1063 // Implement IDisposable Correctly
{
_shortAcivity?.Dispose();
_shortMessage?.Dispose();
_longAcivity?.Dispose();
_longMessage?.Dispose();
}
private sealed class RP : IRedactorProvider
{
private static readonly Redactor _r = new MockRedactor();
public Redactor GetRedactor(DataClassification classification) => _r;
}
internal sealed class MockRedactor : Redactor
{
private const string Template = "[REDACTED]";
public override int GetRedactedLength(ReadOnlySpan<char> source)
{
return Template.Length;
}
public override int Redact(ReadOnlySpan<char> source, Span<char> destination)
{
Template.AsSpan().CopyTo(destination);
return Template.Length;
}
}
}

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -0,0 +1,104 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.Resilience.Options;
using Microsoft.Extensions.Resilience.Polly.Bench.Internals;
using Polly;
namespace Microsoft.Extensions.Resilience.Polly.Bench;
public class Hedging
{
private const int HedgingAttempts = 2;
private readonly TimeSpan _hedgingDelay = TimeSpan.FromMilliseconds(3);
private readonly CancellationToken _cancellationToken = new CancellationTokenSource().Token;
private IAsyncPolicy<Result> _hedgingPolicy = null!;
[GlobalSetup]
public void GlobalSetup()
{
var factory = HedgingUtilities.CreatePolicyFactory();
_hedgingPolicy = factory.CreateHedgingPolicy(
"hedging-policy",
#pragma warning disable CS8622 // Nullability of reference types in type of parameter doesn't match the target delegate (possibly because of nullability attributes).
(HedgingTaskProviderArguments _, [NotNullWhen(true)] out Task<Result>? result) =>
#pragma warning restore CS8622 // Nullability of reference types in type of parameter doesn't match the target delegate (possibly because of nullability attributes).
{
result = HedgingUtilities.SuccessTask;
return true;
},
new HedgingPolicyOptions<Result>
{
HedgingDelay = _hedgingDelay,
MaxHedgedAttempts = HedgingAttempts,
ShouldHandleException = (e) => e is InvalidOperationException,
ShouldHandleResultAsError = r => r == Result.TransientError
});
}
[Benchmark(Baseline = true)]
public Task HedgingManual_Success()
{
return HedgingUtilities.ExecuteWithManualHedging(_successFunc, _successFunc, _hedgingDelay, _cancellationToken);
}
[Benchmark]
public Task Hedging_Success()
{
return _hedgingPolicy.ExecuteAsync(_successFunc, _cancellationToken);
}
[Benchmark]
public Task HedgingManual_SuccessOnSecondaryTry()
{
return HedgingUtilities.ExecuteWithManualHedging(_errorFunc, _successFunc, _hedgingDelay, _cancellationToken);
}
[Benchmark]
public Task HedgingManual_RealAwaiting_SuccessOnSecondaryTry()
{
return HedgingUtilities.ExecuteWithManualHedging(_errorFunc, _longSuccessFunc, _hedgingDelay, _cancellationToken);
}
[Benchmark]
public Task Hedging_SuccessOnSecondaryTry()
{
return _hedgingPolicy.ExecuteAsync(_errorFunc, _cancellationToken);
}
[Benchmark]
public Task HedgingManual_FirstTryThrows_SuccessOnSecondaryTry()
{
return HedgingUtilities.ExecuteWithManualHedging(_exceptionFunc, _successFunc, _hedgingDelay, _cancellationToken);
}
[Benchmark]
public Task Hedging_FirstTryThrows_SuccessOnSecondaryTry()
{
return _hedgingPolicy.ExecuteAsync(_exceptionFunc, _cancellationToken);
}
private static readonly Func<CancellationToken, Task<Result>> _successFunc = SuccessFunc;
private static readonly Func<CancellationToken, Task<Result>> _longSuccessFunc = LongSuccessFunc;
private static readonly Func<CancellationToken, Task<Result>> _errorFunc = ErrorFunc;
private static readonly Func<CancellationToken, Task<Result>> _exceptionFunc = ExceptionFunc;
private static Task<Result> SuccessFunc(CancellationToken cancellationToken) => HedgingUtilities.SuccessTask;
private static async Task<Result> LongSuccessFunc(CancellationToken cancellationToken)
{
await Task.Delay(TimeSpan.FromMilliseconds(100), cancellationToken).ConfigureAwait(false);
return default;
}
private static Task<Result> ErrorFunc(CancellationToken cancellationToken) => HedgingUtilities.TransientErrorTask;
private static Task<Result> ExceptionFunc(CancellationToken cancellationToken) => HedgingUtilities.TransientExceptionTask;
}

Просмотреть файл

@ -0,0 +1,72 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Resilience.Internal;
using Microsoft.Extensions.Telemetry.Metering;
namespace Microsoft.Extensions.Resilience.Polly.Bench.Internals;
internal enum Result
{
Success,
TransientError
}
internal static class HedgingUtilities
{
public static readonly Task<Result> SuccessTask = Task.FromResult(Result.Success);
public static readonly Task<Result> TransientErrorTask = Task.FromResult(Result.TransientError);
public static readonly Task<Result> TransientExceptionTask = Task.FromException<Result>(new InvalidOperationException("Failed hedged attempt."));
public static Resilience.Internal.IPolicyFactory CreatePolicyFactory()
{
var services = new ServiceCollection();
PolicyFactoryServiceCollectionExtensions.AddPolicyFactory<Result>(services);
services.RegisterMetering();
services.AddLogging();
return services.BuildServiceProvider().GetRequiredService<Resilience.Internal.IPolicyFactory>();
}
public static async Task<Result> ExecuteWithManualHedging(
Func<CancellationToken, Task<Result>> executeFunc,
Func<CancellationToken, Task<Result>> retryFunc,
TimeSpan hedginDelay,
CancellationToken cancellationToken)
{
using var delayCancellation = new CancellationTokenSource();
var delay = Task.Delay(hedginDelay, delayCancellation.Token);
var executeTask = executeFunc(cancellationToken);
var finishedTask = await Task.WhenAny(delay, executeTask).ConfigureAwait(false);
if (finishedTask == delay)
{
return await retryFunc(cancellationToken).ConfigureAwait(false);
}
await delayCancellation.CancelAsync().ConfigureAwait(false);
Result result = default;
try
{
result = await executeTask.ConfigureAwait(false);
}
catch (InvalidOperationException)
{
result = Result.TransientError;
}
if (result == Result.TransientError)
{
return await retryFunc(cancellationToken).ConfigureAwait(false);
}
return result;
}
}

Просмотреть файл

@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>Microsoft.Extensions.Resilience</RootNamespace>
<Description>Benchmarks for Microsoft.Extensions.Resilience.</Description>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Libraries\Microsoft.Extensions.Resilience\Microsoft.Extensions.Resilience.csproj" />
<ProjectReference Include="..\..\..\src\Libraries\Microsoft.Extensions.Telemetry.Abstractions\Microsoft.Extensions.Telemetry.Abstractions.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,30 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Telemetry.Metering;
namespace Microsoft.Extensions.Resilience.Bench;
public class PipelineProvider
{
private IResiliencePipelineProvider? _pipelineProvider;
[GlobalSetup]
public void GlobalSetup()
{
var services = new ServiceCollection();
services.AddLogging();
services.RegisterMetering();
services.AddResiliencePipeline<string>("dummy").AddBulkheadPolicy("dummy");
_pipelineProvider = services.BuildServiceProvider().GetRequiredService<IResiliencePipelineProvider>();
}
[Benchmark(Baseline = true)]
public void GetPipeline() => _pipelineProvider!.GetPipeline<string>("dummy");
[Benchmark]
public void GetPipelineByKey() => _pipelineProvider!.GetPipeline<string>("dummy", "dummy-key");
}

Просмотреть файл

@ -0,0 +1,77 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Threading;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Resilience.Internal;
using Microsoft.Extensions.Telemetry.Metering;
using Polly;
using Polly.NoOp;
namespace Microsoft.Extensions.Resilience.Bench;
public class Pipelines
{
private static readonly Task<string> _completed = Task.FromResult("dummy");
private IAsyncPolicy<string>? _bulkheadPolicy;
private IAsyncPolicy<string>? _timeoutPolicy;
private IAsyncPolicy<string>? _circuitBreaker;
private IAsyncPolicy<string>? _retryPolicy;
private IAsyncPolicy<string>? _fallbackPolicy;
private IAsyncPolicy<string>? _hedgingPolicy;
private AsyncNoOpPolicy<string>? _noOp;
private CancellationToken _cancellation;
private Context? _context;
[GlobalSetup]
public void GlobalSetup()
{
var services = new ServiceCollection();
services.AddLogging();
services.RegisterMetering();
services.AddResiliencePipeline<string>(nameof(SupportedPolicies.BulkheadPolicy)).AddBulkheadPolicy("dummy");
services.AddResiliencePipeline<string>(nameof(SupportedPolicies.TimeoutPolicy)).AddTimeoutPolicy("dummy");
services.AddResiliencePipeline<string>(nameof(SupportedPolicies.CircuitBreaker)).AddCircuitBreakerPolicy("dummy");
services.AddResiliencePipeline<string>(nameof(SupportedPolicies.RetryPolicy)).AddRetryPolicy("dummy");
services.AddResiliencePipeline<string>(nameof(SupportedPolicies.FallbackPolicy)).AddFallbackPolicy("dummy", task => _completed);
services.AddResiliencePipeline<string>(nameof(SupportedPolicies.HedgingPolicy)).AddHedgingPolicy("dummy", (HedgingTaskProviderArguments _, out Task<string>? result) =>
{
result = null;
return false;
});
var pipelineProvider = services.BuildServiceProvider().GetRequiredService<IResiliencePipelineProvider>();
_context = new Context();
_bulkheadPolicy = pipelineProvider.GetPipeline<string>(nameof(SupportedPolicies.BulkheadPolicy));
_timeoutPolicy = pipelineProvider.GetPipeline<string>(nameof(SupportedPolicies.TimeoutPolicy));
_circuitBreaker = pipelineProvider.GetPipeline<string>(nameof(SupportedPolicies.CircuitBreaker));
_retryPolicy = pipelineProvider.GetPipeline<string>(nameof(SupportedPolicies.RetryPolicy));
_fallbackPolicy = pipelineProvider.GetPipeline<string>(nameof(SupportedPolicies.FallbackPolicy));
_hedgingPolicy = pipelineProvider.GetPipeline<string>(nameof(SupportedPolicies.HedgingPolicy));
_noOp = Policy.NoOpAsync<string>();
_cancellation = new CancellationTokenSource().Token;
}
[Benchmark(Baseline = true)]
public Task NoOp() => _noOp!.ExecuteAsync(static (_, _) => _completed, _context, _cancellation);
[Benchmark]
public Task Bulkhead() => _bulkheadPolicy!.ExecuteAsync(static (_, _) => _completed, _context, _cancellation);
[Benchmark]
public Task Timeout() => _timeoutPolicy!.ExecuteAsync(static (_, _) => _completed, _context, _cancellation);
[Benchmark]
public Task CircuitBreaker() => _circuitBreaker!.ExecuteAsync(static (_, _) => _completed, _context, _cancellation);
[Benchmark]
public Task Retry() => _retryPolicy!.ExecuteAsync(static (_, _) => _completed, _context, _cancellation);
[Benchmark]
public Task Fallback() => _fallbackPolicy!.ExecuteAsync(static (_, _) => _completed, _context, _cancellation);
[Benchmark]
public Task Hedging() => _hedgingPolicy!.ExecuteAsync(static (_, _) => _completed, _context, _cancellation);
}

Просмотреть файл

@ -0,0 +1,23 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Toolchains.InProcess.Emit;
namespace Microsoft.Extensions.Resilience.Bench;
internal static class Program
{
private static void Main(string[] args)
{
var dontRequireSlnToRunBenchmarks = ManualConfig
.Create(DefaultConfig.Instance)
.AddJob(Job.MediumRun.WithToolchain(InProcessEmitToolchain.Instance))
.AddDiagnoser(MemoryDiagnoser.Default);
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, dontRequireSlnToRunBenchmarks);
}
}

32
build.cmd Normal file
Просмотреть файл

@ -0,0 +1,32 @@
@ECHO OFF
SETLOCAL EnableDelayedExpansion
SET _args=%*
IF "%~1"=="-?" SET _args=-help
IF "%~1"=="/?" SET _args=-help
IF ["%_args%"] == [""] (
:: Perform restore and build, IF no args are supplied.
SET _args=-restore -build
)
FOR %%x IN (%*) DO (
SET _arg=%%x
IF /I "%%x%"=="-coverage" GOTO RUN_CODE_COVERAGE
)
powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0eng\build.ps1""" %_args%"
EXIT /b %ERRORLEVEL%
:RUN_CODE_COVERAGE
SET DOTNET_ROOT=%~dp0.dotnet
:: This tells .NET Core not to go looking for .NET Core in other places
SET DOTNET_MULTILEVEL_LOOKUP=0
dotnet dotnet-coverage collect --settings ./eng/CodeCoverage.config --output ./artifacts/TestResults/ "build.cmd -test -bl"
dotnet reportgenerator -reports:./artifacts/TestResults/*.cobertura.xml -targetdir:./artifacts/TestResults/CoverageResultsHtml -reporttypes:HtmlInline_AzurePipelines
start ./artifacts/TestResults/CoverageResultsHtml/index.html
powershell -ExecutionPolicy ByPass -NoProfile -command "./scripts/ValidateProjectCoverage.ps1 -CoberturaReportXml ./artifacts/TestResults/.cobertura.xml"
EXIT /b %ErrorLevel%

19
build.sh Executable file
Просмотреть файл

@ -0,0 +1,19 @@
#!/usr/bin/env bash
# Stop script if unbound variable found (use ${var:-} if intentional)
set -u
# Stop script if command returns non-zero exit code.
# Prevents hidden errors caused by missing error code propagation.
set -e
set -euo pipefail
if [[ $# < 1 ]]
then
# Perform restore and build, if no args are supplied.
set -- --restore --build;
fi
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
"$DIR/eng/build.sh" "$@"

159
docs/building.md Normal file
Просмотреть файл

@ -0,0 +1,159 @@
# Build instructions
- [Introduction](#introduction)
- [Ubuntu](#ubuntu)
* [Building from command line](#building-from-command-line)
* [Building from Visual Studio Code](#building-from-visual-studio-code)
- [Windows](#windows)
* [Building from command line](#building-from-command-line-1)
* [Building from Visual Studio](#building-from-visual-studio)
* [Building from Visual Studio Code](#building-from-visual-studio-code-1)
- [Build outputs](#build-outputs)
- [Troubleshooting build errors](#troubleshooting-build-errors)
## Introduction
Like many other .NET repositories, this repository uses the [.NET Arcade SDK][arcade-sdk]. With that, most repository interactions are facilitated with `.\eng\common\build.cmd` or `.\eng\common\build.sh`. We added helper scripts to simplify some of the most common interactions with those, such as `restore.cmd`/`restore.sh` and `build.cmd`/`build.sh`.
Also, like all the Arcadified repositories, this repository does **not** build using your machine-wide installed version of the .NET SDK. Instead it builds using the repo-local .NET SDK specified in the [`global.json`](..\global.json) file located in the repository root.<br />
:warning: This also means that you **cannot** double click on any of the projects or a solution file in this repository and open those in Visual Studio. Generally, it won't work as Visual Studio won't be able to resolve the required .NET SDK. You will need to use our helper scripts provided for your convenience.
However, unlike pretty much all .NET repositories, this repository does not contain a solution file due to the number of projects in the solutions and the target framework monikers (TFMs) those projects use. It's very unlikely that you, as a developer, will be dealing with all projects in this repository at the same time. Instead, we expect that you will work on a subset of projects, using a "filtered" solution generated with the [slngen tool][slngen-tool]. Please read below for detailed instructions.
## Ubuntu
### Building from command line
#### TL;DR
Building the solution is as easy as running:
```bash
$ ./build.sh
```
#### Various scripts to build and test the solution
The repo provides the following helper scripts for your convenience:
* `restore.sh` - this script will install the required .NET SDK, .NET tools and the toolset.<br />
This script is equivalent to running `./build.sh --restore`.
* `build.sh` - this is a "one-stop shop" script that accepts a whole plethora of commands.<br />
Here are few commands that you will likely use the most:
- `build.sh`: without any parameters this is equivalent to running `./build.sh --restore --build`.
- `build.sh --restore`: to install the required .NET SDK, .NET tools and the toolset. This is equivalent to running `./restore.sh`.
- `build.sh --build`: to build the solution<sup>1</sup>.
- `build.sh --test`: to run all unit tests in the solution<sup>1</sup>.
- `build.sh --vs <keywords>`: to generate a "filtered" solution and save it as `SDK.sln`. It also performs the "restore" operation. For example: `./build.sh --vs Http,Fakes`.<br />
If for some reason you wish to generate a solution with all projects you can pass `*` for the keyword, e.g.: `./build.sh -vs '*'` (Note: you have to escape the asterisk or use `set -f` to turn off expansion).<br />
> Under the hood, this invokes `scripts/Slngen.ps1` script, which in turn executes [slngen tool][slngen-tool]. If you want to customize how the "filtered" solution is generated, you will need to invoke `scripts/Slngen.ps1` script directly.<br />
Run `./scripts/Slngen.ps1 -help` for more details.
To find out more about the script and its parameters run: `./build.sh --help`.
* `start-code.sh` - this script sets up necessary environmental variables and opens the repository in VS Code, so that you can interact with the repository in "dotnet"-way, that is run `dotnet` commands from the VS Code's terminal.
### Building from Visual Studio Code
To open the solution in VS Code run the following command:
```bash
$ ./start-code.sh
```
This sets up necessary environmental variables and opens the repository in VS Code. It is advisable that you continue to interact with the solution (i.e., restore, build or test) via the [helper scripts described above](#building-from-command-line), however, it should be generally possible to interact with the repository in "dotnet"-way, that is run `dotnet` commands from the VS Code's terminal.
## Windows
### Building from command line
#### TL;DR
Building the solution is as easy as running:
```bash
> build.cmd
```
#### Various scripts to build and test the solution
* `restore.cmd` - this script will install the required .NET SDK, .NET tools and the toolset.<br />
This script is equivalent to running `.\build.cmd -restore`.
* `build.cmd` - this is a "one-stop shop" script that accepts a whole plethora of commands.<br />
Here are few commands that you will likely use the most:
- `build.cmd`: without any parameters this is equivalent to running `.\build.cmd -restore -build`.
- `build.cmd -restore`: to install the required .NET SDK, .NET tools and the toolset. This is equivalent to running `.\restore.cmd`.
- `build.cmd -build`: to build the solution<sup>1</sup>.
- `build.cmd -test`: to run all unit tests in the solution<sup>1</sup>.
- `build.cmd -vs <keywords>`: to generate a "filtered" solution, save it as `SDK.sln` and then open in Visual Studio. For example: `.\build.cmd -vs Http,Fakes`.<br />
If for some reason you wish to generate a solution with all projects you can pass `*` for the keyword, e.g.: `.\build.cmd -vs *`.<br />
> Under the hood, this invokes `scripts\Slngen.ps1` script, which in turn executes [slngen tool][slngen-tool]. If you want to customize how the "filtered" solution is generated, you will need to invoke `scripts\Slngen.ps1` script directly.<br />
Run `.\scripts\Slngen.ps1 -help` for more details.
To find out more about the script and its parameters run: `.\build.cmd -help`.
### Building from Visual Studio
#### TL;DR
Generating a new solution and opening it in Visual Studio is as easy as running:
```powershell
> build.cmd -vs <keywords>
```
If you already have a solution you'd like to open in Visual Studio then run the following command:
```powershell
> start-vs.cmd
```
#### Various scripts to build and test the solution
1. If you don't have a solution file, or you wish to generate a new one: run `.\restore.cmd -vs <keywords>`.
1. If you have a solution file already (e.g., SDK.sln), then you can simply run `.\start-vs.cmd`.
1. (Advanced) If you want to customize how the "filtered" solution is generated, you will need to invoke `scripts\Slngen.ps1` script directly followed by `start-vs.cmd`.<br />
Run `.\scripts\Slngen.ps1 -help` for more details.
### Building from Visual Studio Code
To open the solution in VS Code run the following command:
```powershell
> start-code.cmd
```
This sets up necessary environmental variables and opens the repository in VS Code. It is advisable that you continue to interact with the solution (i.e., restore, build or test) via the [helper scripts described above](#building-from-command-line-1), however, it should be generally possible to interact with the repository in "dotnet"-way, that is run `dotnet` commands from the VS Code's terminal.
## Build outputs
* All build outputs are generated under the `artifacts` folder.
* Binaries are under `artifacts\bin`.
* Logs are found under `artifacts\log`.
* Packages are found under `artifacts\packages`.
## Troubleshooting build errors
* Most build errors are compile errors and can be dealt with accordingly.
* Other error may be from MSBuild tasks. You need to examine the build logs to investigate.
* The logs are generated at `.\artifacts\log\Debug\Build.binlog`
* The file format is an MSBuild Binary Log. Install the [MSBuild Structured Log Viewer][msbuild-log-viewer] to view them.
* Windows Forms uses Visual Studio MSBuild but for certain features we require the latest MSBuild from .NET Core/.NET SDK. If you are on an official version of [Visual Studio][VS-download] (i.e. not a Preview version), then you may need to enable previews for .NET Core/.NET SDKs in VS.
* you can do this in VS under Tools->Options->Environment->Preview Features->Use previews of the .Net Core SDK (Requires restart)
---
1. **"Solution"** means the collections of projects specified in `eng/build.proj` or an actual "sln" file at the root of the repository that represents the generated "filtered" solution (e.g., `SDK.sln`).
[comment]: <> (URI Links)
[arcade-sdk]: https://github.com/dotnet/arcade/blob/main/Documentation/Overview.md
[msbuild-log-viewer]: https://msbuildlog.com/
[slngen-tool]: https://github.com/microsoft/slngen
[VS-download]: https://visualstudio.microsoft.com/downloads/

Просмотреть файл

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<!-- https://github.com/dotnet/arcade/blob/9a4d4f51/Documentation/ArcadeSdk.md#engaftersolutionbuildtargets-optional -->
</Project>

15
eng/Build.props Normal file
Просмотреть файл

@ -0,0 +1,15 @@
<!-- This file gets automatically imported by Arcade infrastructure when calling the build scripts -->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<RestoreUseStaticGraphEvaluation Condition="'$(DotNetBuildFromSource)' != 'true'">true</RestoreUseStaticGraphEvaluation>
<!-- This is set to false as an optimization to use Arcade's restore. -->
<RestoreUsingNuGetTargets>false</RestoreUsingNuGetTargets>
</PropertyGroup>
<ItemGroup>
<!-- Set the project to build as this repo doesn't have a solution file in the root of the repo -->
<ProjectToBuild Condition="'$(DirectoryToBuild)' == ''" Include="$(MSBuildThisFileDirectory)build.proj" />
</ItemGroup>
</Project>

37
eng/CodeCoverage.config Normal file
Просмотреть файл

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<Configuration>
<Format>cobertura</Format>
<CodeCoverage>
<ModulePaths>
<Include>
<ModulePath>.*Microsoft.*\.dll$</ModulePath>
<ModulePath>.*System.*\.dll$</ModulePath>
</Include>
<Exclude>
<ModulePath>.*tests\.dll</ModulePath>
<ModulePath>.*xunit.*</ModulePath>
<ModulePath>.*moq.*</ModulePath>
</Exclude>
</ModulePaths>
<!-- Match attributes on any code element: -->
<Attributes>
<Exclude>
<!-- Don't forget "Attribute" at the end of the name -->
<Attribute>^System\.Diagnostics\.DebuggerHiddenAttribute$</Attribute>
<Attribute>^System\.Diagnostics\.DebuggerNonUserCodeAttribute$</Attribute>
<Attribute>^System\.CodeDom\.Compiler\.GeneratedCodeAttribute$</Attribute>
<Attribute>^System\.Diagnostics\.CodeAnalysis\.ExcludeFromCodeCoverageAttribute$</Attribute>
</Exclude>
</Attributes>
<!-- When set to True, dynamic native instrumentation will be enabled. -->
<EnableDynamicNativeInstrumentation>false</EnableDynamicNativeInstrumentation>
<!-- When set to True, instrumented binaries on disk are removed and original files are restored. -->
<EnableStaticNativeInstrumentationRestore>false</EnableStaticNativeInstrumentationRestore>
<EnableStaticNativeInstrumentation>false</EnableStaticNativeInstrumentation>
<UseVerifiableInstrumentation>false</UseVerifiableInstrumentation>
</CodeCoverage>
</Configuration>

20
eng/Common.runsettings Normal file
Просмотреть файл

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
<RunConfiguration>
<TargetPlatform>x64</TargetPlatform>
<DisableAppDomain>true</DisableAppDomain>
</RunConfiguration>
<DataCollectionRunSettings>
<DataCollectors>
<DataCollector friendlyName="XPlat code coverage">
<Configuration>
<Format>cobertura</Format>
<Exclude>[*.Tests]*</Exclude> <!-- [Assembly-Filter]Type-Filter -->
<Include>[Microsoft.*]*,[System*]*</Include>
<ExcludeByAttribute>ExcludeFromCodeCoverageAttribute,DebuggerNonUserCodeAttribute,DebuggerHiddenAttribute,GeneratedCodeAttribute</ExcludeByAttribute>
</Configuration>
</DataCollector>
</DataCollectors>
</DataCollectionRunSettings>
</RunSettings>

Просмотреть файл

@ -0,0 +1 @@
{}

Просмотреть файл

@ -0,0 +1,33 @@
<Project>
<!-- Code analysis stuff -->
<PropertyGroup>
<RunAnalyzers>false</RunAnalyzers>
<RunAnalyzersDuringBuild>false</RunAnalyzersDuringBuild>
<EnforceCodeStyleInBuild>false</EnforceCodeStyleInBuild>
<EnableNETAnalyzers>false</EnableNETAnalyzers>
</PropertyGroup>
<PropertyGroup Condition="'$(SkipAnalyzers)' != 'true'">
<RunAnalyzers>true</RunAnalyzers>
<RunAnalyzersDuringBuild>true</RunAnalyzersDuringBuild>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<AnalysisLevel>latest</AnalysisLevel>
<SkipGlobalAnalyzerConfigForPackage>true</SkipGlobalAnalyzerConfigForPackage>
</PropertyGroup>
<!-- The static analyzers we use -->
<ItemGroup Condition="'$(SkipAnalyzers)' != 'true'">
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
<PackageReference Include="SonarAnalyzer.CSharp" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
<PackageReference Include="StyleCop.Analyzers.Unstable" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
<AdditionalFiles Include="$(RepositoryEngineeringDir)\Stylecop.json" Visible="false" />
</ItemGroup>
<ItemGroup Condition="'$(SkipAnalyzers)' != 'true'">
<!-- We can't use $(RepoRoot) here as slngen tool is failing to resolve it... -->
<ProjectReference Condition="'$(SkipExtraAnalyzers)' != 'true'" Include="$(MSBuildThisFileDirectory)\..\..\src\Analyzers\Microsoft.Extensions.ExtraAnalyzers\Microsoft.Extensions.ExtraAnalyzers.Roslyn4.0\Microsoft.Extensions.ExtraAnalyzers.Roslyn4.0.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" Private="false" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
<ProjectReference Condition="'$(SkipLocalAnalyzers)' != 'true'" Include="$(MSBuildThisFileDirectory)\..\..\src\Analyzers\Microsoft.Extensions.LocalAnalyzers\Microsoft.Extensions.LocalAnalyzers.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" Private="false" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,110 @@
<Project>
<!--
ANALYZER SHIPPING AND MULTI-TARGETTING SUPPORT
Sections below add support for shipping and multi-targeting of C# analyzers.
Borrowed from .NET:
https://github.com/dotnet/runtime/blob/main/eng/packaging.targets
-->
<Target Name="IncludeAnalyzersInPackage" Condition="'@(AnalyzerReference)' != ''">
<!-- Call a target in the analyzer project to get all the files it would normally place in a package.
These will be returned as items with identity pointing to the built file, and PackagePath metadata
set to their location in the package. IsSymbol metadata will be set to distinguish symbols. -->
<MSBuild Projects="@(AnalyzerReference)"
Targets="GetAnalyzerPackFiles">
<Output TaskParameter="TargetOutputs" ItemName="_AnalyzerFile" />
</MSBuild>
<ItemGroup>
<Content Include="@(_AnalyzerFile)" Pack="True" Condition="!%(_AnalyzerFile.IsSymbol)" />
<!-- Symbols don't honor PackagePath. By default they are placed in lib/%(TargetFramework).
Pack does honor TargetPath and does Path.Combine("lib/%(TargetFramework)", "%(TargetPath)"),
so a rooted path value for TargetPath will override lib.
https://github.com/NuGet/Home/issues/10860 -->
<_TargetPathsToSymbols Include="@(_AnalyzerFile)" TargetPath="/%(_AnalyzerFile.PackagePath)" Condition="%(_AnalyzerFile.IsSymbol)" />
</ItemGroup>
</Target>
<PropertyGroup>
<_MultiTargetRoslynComponentTargetsTemplate>$(MSBuildThisFileDirectory)MultiTargetRoslynComponent.targets.template</_MultiTargetRoslynComponentTargetsTemplate>
<MultiTargetRoslynComponentTargetsFileIntermediatePath>$(IntermediateOutputPath)MultiTargetRoslynComponent.targets</MultiTargetRoslynComponentTargetsFileIntermediatePath>
<IncludeMultiTargetRoslynComponentTargets Condition="'$(IncludeMultiTargetRoslynComponentTargets)' == ''">true</IncludeMultiTargetRoslynComponentTargets>
</PropertyGroup>
<!-- In packages that contain Analyzers, include a .targets file that will select the correct analyzer. -->
<Target Name="IncludeMultiTargetRoslynComponentTargetsInPackage"
AfterTargets="IncludeAnalyzersInPackage"
Condition="'@(AnalyzerReference)' != '' AND '$(IncludeMultiTargetRoslynComponentTargets)' == 'true'"
DependsOnTargets="GenerateMultiTargetRoslynComponentTargetsFile">
<ItemGroup>
<Content Include="$(MultiTargetRoslynComponentTargetsFileIntermediatePath)"
PackagePath="buildTransitive\MultiTargetRoslynComponent.targets"
Pack="True" />
</ItemGroup>
</Target>
<Target Name="GenerateMultiTargetRoslynComponentTargetsFile"
Inputs="$(MSBuildProjectFullPath);_MultiTargetRoslynComponentTargetsTemplate"
Outputs="$(MultiTargetRoslynComponentTargetsFileIntermediatePath)">
<PropertyGroup>
<_MultiTargetRoslynComponentTargetPrefix>$(PackageId.Replace('.', '_'))</_MultiTargetRoslynComponentTargetPrefix>
<DisableSourceGeneratorPropertyName Condition="'$(DisableSourceGeneratorPropertyName)' == ''">Disable$(PackageId.Replace('.', ''))SourceGenerator</DisableSourceGeneratorPropertyName>
</PropertyGroup>
<WriteLinesToFile File="$(MultiTargetRoslynComponentTargetsFileIntermediatePath)"
Lines="$([System.IO.File]::ReadAllText('$(_MultiTargetRoslynComponentTargetsTemplate)')
.Replace('{TargetPrefix}', '$(_MultiTargetRoslynComponentTargetPrefix)')
.Replace('{NuGetPackageId}', '$(PackageId)')
.Replace('{DisableSourceGeneratorPropertyName}', '$(DisableSourceGeneratorPropertyName)'))"
Overwrite="true" />
</Target>
<PropertyGroup>
<BuildAnalyzerReferences>$(BuildProjectReferences)</BuildAnalyzerReferences>
<BuildAnalyzerReferences Condition="'$(BuildingInsideVisualStudio)' == 'true'">false</BuildAnalyzerReferences>
</PropertyGroup>
<ItemGroup>
<!-- Ensure AnalyzerReference items are restored and built
The target framework of Analyzers has no relationship to that of the referencing project,
so we don't apply TargetFramework filters nor do we pass in TargetFramework.
When BuildProjectReferences=false we make sure to set BuildReference=false to make
sure not to try to call GetTargetPath in the outerbuild of the analyzer project. -->
<ProjectReference Include="@(AnalyzerReference)"
SkipGetTargetFrameworkProperties="true"
UndefineProperties="TargetFramework"
ReferenceOutputAssembly="false"
PrivateAssets="all"
Condition="'$(BuildingSlnForDocs)' != 'true'"
BuildReference="$(BuildAnalyzerReferences)" />
</ItemGroup>
<Target Name="GetAnalyzerPackFiles"
DependsOnTargets="$(GenerateNuspecDependsOn)"
Returns="@(_AnalyzerPackFile)">
<PropertyGroup>
<_analyzerPath>analyzers/dotnet</_analyzerPath>
<_analyzerPath Condition="'$(AnalyzerRoslynVersion)' != ''">$(_analyzerPath)/roslyn$(AnalyzerRoslynVersion)</_analyzerPath>
<_analyzerPath Condition="'$(AnalyzerLanguage)' != ''">$(_analyzerPath)/$(AnalyzerLanguage)</_analyzerPath>
</PropertyGroup>
<ItemGroup>
<!-- Packs *.dll -->
<_AnalyzerPackFile IsSymbol="false"
Include="%(_BuildOutputInPackage.FinalOutputPath)"
TargetPath="%(_BuildOutputInPackage.TargetPath)"
TargetFramework="%(_BuildOutputInPackage.TargetFramework)" />
<!-- Packs *.pdb -->
<_AnalyzerPackFile IsSymbol="true"
Include="%(_TargetPathsToSymbols.FinalOutputPath)"
TargetPath="%(_TargetPathsToSymbols.TargetPath)"
TargetFramework="%(_TargetPathsToSymbols.TargetFramework)" />
<_AnalyzerPackFile PackagePath="$(_analyzerPath)/%(TargetPath)" />
</ItemGroup>
<Error Condition="'%(_AnalyzerPackFile.TargetFramework)' != 'netstandard2.0'"
Text="Analyzers must only target netstandard2.0 since they run in the compiler which targets netstandard2.0. The following files were found to target '%(_AnalyzerPackFile.TargetFramework)': @(_AnalyzerPackFile)" />
</Target>
</Project>

Просмотреть файл

@ -0,0 +1,21 @@
<Project>
<ItemGroup Condition="'$(UseLoggingGenerator)' == 'true' and '$(BuildingSlnForDocs)' != 'true'">
<ProjectReference Include="$(MSBuildThisFileDirectory)\..\..\src\Generators\Microsoft.Gen.Logging\Roslyn4.0\Microsoft.Gen.Logging.Roslyn4.0.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" Private="false" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
</ItemGroup>
<ItemGroup Condition="'$(UseEnumStringsGenerator)' == 'true' and '$(BuildingSlnForDocs)' != 'true'">
<ProjectReference Include="$(MSBuildThisFileDirectory)\..\..\src\Generators\Microsoft.Gen.EnumStrings\Roslyn4.0\Microsoft.Gen.EnumStrings.Roslyn4.0.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" Private="false" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
</ItemGroup>
<ItemGroup Condition="'$(UseOptionsValidationGenerator)' == 'true' and '$(BuildingSlnForDocs)' != 'true'">
<ProjectReference Include="$(MSBuildThisFileDirectory)\..\..\src\Generators\Microsoft.Gen.OptionsValidation\Roslyn4.0\Microsoft.Gen.OptionsValidation.Roslyn4.0.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" Private="false" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
</ItemGroup>
<ItemGroup Condition="'$(UseMeteringGenerator)' == 'true' and '$(BuildingSlnForDocs)' != 'true'">
<ProjectReference Include="$(MSBuildThisFileDirectory)\..\..\src\Generators\Microsoft.Gen.Metering\Roslyn4.0\Microsoft.Gen.Metering.Roslyn4.0.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" Private="false" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
</ItemGroup>
<ItemGroup Condition="'$(UseContextualOptionsGenerator)' == 'true' and '$(BuildingSlnForDocs)' != 'true'">
<ProjectReference Include="$(MSBuildThisFileDirectory)\..\..\src\Generators\Microsoft.Gen.ContextualOptions\Roslyn4.0\Microsoft.Gen.ContextualOptions.Roslyn4.0.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" Private="false" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,10 @@
<Project>
<PropertyGroup Condition="'$(GenerateMetricDefinitionReport)' == ''">
<GenerateMetricDefinitionReport>false</GenerateMetricDefinitionReport>
</PropertyGroup>
<ItemGroup Condition="'$(GenerateMetricDefinitionReport)' == 'true'">
<CompilerVisibleProperty Include="GenerateMetricDefinitionReport" />
<CompilerVisibleProperty Include="OutputPath" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,57 @@
<Project>
<ItemGroup Condition="'$(InjectDiagnosticAttributesOnLegacy)' == 'true' AND ('$(TargetFramework)' == 'net462' or '$(TargetFramework)' == 'net472' or '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netcoreapp3.1')">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\LegacySupport\DiagnosticAttributes\*.cs" LinkBase="LegacySupport\DiagnosticAttributes" />
</ItemGroup>
<ItemGroup Condition="'$(InjectIsExternalInitOnLegacy)' == 'true' AND ('$(TargetFramework)' == 'net462' or '$(TargetFramework)' == 'net472' or '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netcoreapp3.1')">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\LegacySupport\IsExternalInit\*.cs" LinkBase="LegacySupport\IsExternalInit" />
</ItemGroup>
<ItemGroup Condition="'$(InjectTrimAttributesOnLegacy)' == 'true' AND ('$(TargetFramework)' == 'net462' or '$(TargetFramework)' == 'net472' or '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netcoreapp3.1')">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\LegacySupport\TrimAttributes\*.cs" LinkBase="LegacySupport\TrimAttributes" />
</ItemGroup>
<ItemGroup Condition="'$(InjectCallerAttributesOnLegacy)' == 'true' AND ('$(TargetFramework)' == 'net462' or '$(TargetFramework)' == 'net472' or '$(TargetFramework)' == 'netstandard2.0')">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\LegacySupport\CallerAttributes\*.cs" LinkBase="LegacySupport\CallerAttributes" />
</ItemGroup>
<ItemGroup Condition="'$(InjectSkipLocalsInitAttributeOnLegacy)' == 'true' AND ('$(TargetFramework)' == 'net462' or '$(TargetFramework)' == 'net472' or '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netcoreapp3.1')">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\LegacySupport\SkipLocalsInitAttribute\*.cs" LinkBase="LegacySupport\SkipLocalsInitAttribute" />
</ItemGroup>
<ItemGroup Condition="'$(InjectStringHashOnLegacy)' == 'true' AND ('$(TargetFramework)' == 'net462' or '$(TargetFramework)' == 'net472' or '$(TargetFramework)' == 'netstandard2.0')">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\LegacySupport\StringHash\*.cs" LinkBase="LegacySupport\StringHash" />
</ItemGroup>
<ItemGroup Condition="'$(InjectBitOperationsOnLegacy)' == 'true' AND ('$(TargetFramework)' == 'net462' or '$(TargetFramework)' == 'net472' or '$(TargetFramework)' == 'netstandard2.0')">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\LegacySupport\BitOperations\*.cs" LinkBase="LegacySupport\BitOperations" />
</ItemGroup>
<ItemGroup Condition="'$(InjectStringBuilderOnLegacy)' == 'true' AND ('$(TargetFramework)' == 'net462' or '$(TargetFramework)' == 'net472' or '$(TargetFramework)' == 'netstandard2.0')">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\LegacySupport\StringBuilderExtensions\*.cs" LinkBase="LegacySupport\StringBuilderExtensions" />
</ItemGroup>
<ItemGroup Condition="'$(InjectStringSyntaxAttributeOnLegacy)' == 'true' AND ('$(TargetFramework)' == 'net462' or '$(TargetFramework)' == 'net472' or '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netcoreapp3.1' or '$(TargetFramework)' == 'net6.0')">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\LegacySupport\StringSyntaxAttribute\*.cs" LinkBase="LegacySupport\StringSyntaxAttribute" />
</ItemGroup>
<ItemGroup Condition="'$(InjectGetOrAddOnLegacy)' == 'true' AND ('$(TargetFramework)' == 'net462' or '$(TargetFramework)' == 'net472' or '$(TargetFramework)' == 'netstandard2.0')">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\LegacySupport\GetOrAdd\*.cs" LinkBase="LegacySupport\GetOrAdd" />
</ItemGroup>
<ItemGroup Condition="'$(InjectDictionaryExtensionsOnLegacy)' == 'true' AND ('$(TargetFramework)' == 'net462' or '$(TargetFramework)' == 'net472' or '$(TargetFramework)' == 'netstandard2.0')">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\LegacySupport\DictionaryExtensions\*.cs" LinkBase="LegacySupport\DictionaryExtensions" />
</ItemGroup>
<ItemGroup Condition="'$(InjectTaskWaitAsyncOnLegacy)' == 'true' AND ('$(TargetFramework)' == 'net462' or '$(TargetFramework)' == 'net472' or '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netcoreapp3.1')">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\LegacySupport\TaskWaitAsync\*.cs" LinkBase="LegacySupport\TaskWaitAsync" />
</ItemGroup>
<ItemGroup Condition="'$(InjectxxH3OnLegacy)' == 'true' AND ('$(TargetFramework)' == 'net462' or '$(TargetFramework)' == 'net472' or '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netcoreapp3.1' or '$(TargetFramework)' == 'net6.0' or '$(TargetFramework)' == 'net7.0')">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\LegacySupport\xxH3\*.cs" LinkBase="LegacySupport\xxH3" />
</ItemGroup>
<ItemGroup Condition="'$(InjectExperimentalAttributeOnLegacy)' == 'true' AND ('$(TargetFramework)' == 'net462' or '$(TargetFramework)' == 'net472' or '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netcoreapp3.1' or '$(TargetFramework)' == 'net6.0' or '$(TargetFramework)' == 'net7.0' or '$(TargetFramework)' == 'net8.0')">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\LegacySupport\ExperimentalAttribute\*.cs" LinkBase="LegacySupport\ExperimentalAttribute" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,6 @@
<Project>
<PropertyGroup Condition="'$(InjectxxH3OnLegacy)' == 'true'">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<InjectBitOperationsOnLegacy>true</InjectBitOperationsOnLegacy>
</PropertyGroup>
</Project>

Просмотреть файл

@ -0,0 +1,69 @@
<Project>
<Target Name="_{TargetPrefix}GatherAnalyzers">
<ItemGroup>
<_{TargetPrefix}Analyzer Include="@(Analyzer)" Condition="'%(Analyzer.NuGetPackageId)' == '{NuGetPackageId}'" />
</ItemGroup>
</Target>
<Target Name="_{TargetPrefix}AnalyzerMultiTargeting"
Condition="'$(SupportsRoslynComponentVersioning)' != 'true'"
AfterTargets="ResolvePackageDependenciesForBuild;ResolveNuGetPackageAssets"
DependsOnTargets="_{TargetPrefix}GatherAnalyzers">
<ItemGroup>
<!-- Remove our analyzers targeting roslyn4.x -->
<Analyzer Remove="@(_{TargetPrefix}Analyzer)"
Condition="$([System.String]::Copy('%(_{TargetPrefix}Analyzer.Identity)').IndexOf('roslyn4')) >= 0"/>
</ItemGroup>
</Target>
<Target Name="_{TargetPrefix}RemoveAnalyzers"
Condition="'$({DisableSourceGeneratorPropertyName})' == 'true'"
AfterTargets="ResolvePackageDependenciesForBuild;ResolveNuGetPackageAssets"
DependsOnTargets="_{TargetPrefix}GatherAnalyzers">
<!-- Remove all our analyzers -->
<ItemGroup>
<Analyzer Remove="@(_{TargetPrefix}Analyzer)" />
</ItemGroup>
</Target>
<!--
Microsoft's mandatory guardian build analysis removes all analyzers, including code generators,
from a csproj then adds back only their own. But our projects need generators to build, so we
need a mechanism to add them back.
See: https://dev.azure.com/securitytools/SecurityIntegration/_git/Microsoft.Guardian?path=%2Fsrc%2FMicrosoft.Guardian.RoslynAnalyzers%2FRoslynEnvironment.cs
Workaround is done in two steps (targets):
1. We make a snapshot of set of analyzers BEFORE guardian build analysis removes them,
but AFTER we have evaluated which of them based on the .NET toolchain we should use
(Roslyn3.8 vs. Roslyn4.0 saga).
2. Re-add subset of analyzers back AFTER guardian build analysis runs but BEFORE core
compilation starts, effectively reverting the changes done. Note that this is only
done for analyzers that are shipped with this package only.
-->
<Target Name="_{TargetPrefix}CreateAnalyzerSnapshot"
Condition="'$(GdnRoslynAnalyzersRunId)' != ''"
AfterTargets="_{TargetPrefix}AnalyzerMultiTargeting;_{TargetPrefix}RemoveAnalyzers">
<CreateItem Include="@(Analyzer)">
<Output ItemName="_{TargetPrefix}AnalyzerSnapshot" TaskParameter="Include"/>
</CreateItem>
</Target>
<Target Name="_{TargetPrefix}ReAddCodeGenerators"
Condition="'$(GdnRoslynAnalyzersRunId)' != ''"
AfterTargets="ResolveCodeAnalysisRuleSet"
BeforeTargets="CoreCompile"
DependsOnTargets="_{TargetPrefix}CreateAnalyzerSnapshot">
<ItemGroup>
<Analyzer Include="@(_{TargetPrefix}AnalyzerSnapshot)"
Condition="'%(_{TargetPrefix}AnalyzerSnapshot.NuGetPackageId)' == '{NuGetPackageId}'"/>
</ItemGroup>
</Target>
</Project>

Просмотреть файл

@ -0,0 +1,31 @@
<Project>
<PropertyGroup>
<!-- Arcade SDK configures SignAssembly, and this repo has historically been using SignArtifacts -->
<SignArtifacts>$(SignAssembly)</SignArtifacts>
<!-- Arcade SDK marks all but *.pkgproj as non-packable, we need to override. -->
<IsPackable>true</IsPackable>
</PropertyGroup>
<!-- strong name signing control -->
<PropertyGroup Condition="'$(SignArtifacts)' == 'true' ">
<DelaySign>true</DelaySign>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)\MSSharedLibSN2048.snk</AssemblyOriginatorKeyFile>
<PublicKey>002400000c80000014010000060200000024000052534131000800000100010085aad0bef0688d1b994a0d78e1fd29fc24ac34ed3d3ac3fb9b3d0c48386ba834aa880035060a8848b2d8adf58e670ed20914be3681a891c9c8c01eef2ab22872547c39be00af0e6c72485d7cfd1a51df8947d36ceba9989106b58abe79e6a3e71a01ed6bdc867012883e0b1a4d35b1b5eeed6df21e401bb0c22f2246ccb69979dc9e61eef262832ed0f2064853725a75485fa8a3efb7e027319c86dec03dc3b1bca2b5081bab52a627b9917450dfad534799e1c7af58683bdfa135f1518ff1ea60e90d7b993a6c87fd3dd93408e35d1296f9a7f9a97c5db56c0f3cc25ad11e9777f94d138b3cea53b9a8331c2e6dcb8d2ea94e18bf1163ff112a22dbd92d429a</PublicKey>
</PropertyGroup>
<!-- packaging control -->
<PropertyGroup>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<!-- packaging metadata -->
<PropertyGroup>
<Copyright>$(CopyrightNetFoundation)</Copyright>
<PackageProjectUrl>https://dot.net/</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>
</Project>

Просмотреть файл

@ -0,0 +1,90 @@
<Project>
<!-- Pack analyzers -->
<PropertyGroup>
<BeforePack>IncludeAnalyzersInPackage;$(BeforePack)</BeforePack>
<BuildAnalyzerReferences>$(BuildProjectReferences)</BuildAnalyzerReferences>
<BuildAnalyzerReferences Condition="'$(BuildingInsideVisualStudio)' == 'true'">false</BuildAnalyzerReferences>
</PropertyGroup>
<!-- packaging control -->
<PropertyGroup>
<IsPackable Condition="'$(Stage)' == ''">false</IsPackable>
<BeforePack>$(BeforePack);_VerifyMinimumSupportedTfmForPackagingIsUsed;_AddNETStandardCompatErrorFileForPackaging</BeforePack>
</PropertyGroup>
<!-- Include a compat warning for users trying to use our packages on unsupported TFMs -->
<ItemGroup>
<NETStandardCompatError Include="$(ConditionalNet462)"
Supported="$(MinimumSupportedTfmForPackaging)"
Condition="'$(MinimumSupportedTfmForPackaging)' != '' and
'$(ConditionalNet462)' != '' and
($(TargetFrameworks.Contains('$(MinimumSupportedTfmForPackaging)')) and $(TargetFrameworks.Contains('$(ConditionalNet462)')))" />
<NETStandardCompatError Include="netcoreapp3.1"
Supported="$(MinimumSupportedTfmForPackaging)"
Condition="'$(MinimumSupportedTfmForPackaging)' != '' and
($(TargetFrameworks.Contains('$(MinimumSupportedTfmForPackaging)')) and $(TargetFrameworks.Contains('netcoreapp3.1')))" />
</ItemGroup>
<!-- Verify that the minimum supported TFM is actually used. -->
<Target Name="_VerifyMinimumSupportedTfmForPackagingIsUsed"
Condition="'$(IsPackable)' == 'true' and '$(DisableNETStandardCompatErrors)' != 'true'">
<Error Text="$TargetFrameworks ('$(TargetFrameworks)') does not contain $MinimumSupportedTfmForPackaging ('$(MinimumSupportedTfmForPackaging)')."
Condition="!$(TargetFrameworks.Contains('$(MinimumSupportedTfmForPackaging)'))" />
</Target>
<!-- Add targets file that marks selected TFMs as unsupported. -->
<Target Name="_AddNETStandardCompatErrorFileForPackaging"
Condition="'@(NETStandardCompatError)' != '' and '$(DisableNETStandardCompatErrors)' != 'true'"
Inputs="%(NETStandardCompatError.Identity)"
Outputs="unused">
<PropertyGroup>
<_NETStandardCompatErrorFilePath>$(BaseIntermediateOutputPath)netstandardcompaterror_%(NETStandardCompatError.Identity).targets</_NETStandardCompatErrorFilePath>
<_NETStandardCompatErrorFileTarget>NETStandardCompatError_$(PackageId.Replace('.', '_'))_$([System.String]::new('%(NETStandardCompatError.Supported)').Replace('.', '_'))</_NETStandardCompatErrorFileTarget>
<_NETStandardCompatErrorFileContent>
<![CDATA[<Project InitialTargets="$(_NETStandardCompatErrorFileTarget)">
<Target Name="$(_NETStandardCompatErrorFileTarget)"
Condition="'%24(SuppressTfmSupportBuildWarnings)' == ''">
<Warning Text="$(PackageId) $(PackageVersion) doesn't support %24(TargetFramework) and has not been tested with it. Consider upgrading your TargetFramework to %(NETStandardCompatError.Supported) or later. You may also set &lt%3BSuppressTfmSupportBuildWarnings&gt%3Btrue&lt%3B/SuppressTfmSupportBuildWarnings&gt%3B in the project file to ignore this warning and attempt to run in this unsupported configuration at your own risk." />
</Target>
</Project>]]>
</_NETStandardCompatErrorFileContent>
<_NETStandardCompatErrorPlaceholderFilePackagePath>buildTransitive$([System.IO.Path]::DirectorySeparatorChar)%(NETStandardCompatError.Supported)</_NETStandardCompatErrorPlaceholderFilePackagePath>
<PlaceholderFile>$(RepositoryEngineeringDir)_._</PlaceholderFile>
</PropertyGroup>
<WriteLinesToFile File="$(_NETStandardCompatErrorFilePath)"
Lines="$(_NETStandardCompatErrorFileContent)"
Overwrite="true"
WriteOnlyWhenDifferent="true" />
<ItemGroup>
<_PackageBuildFile Include="@(None->Metadata('PackagePath'));
@(Content->Metadata('PackagePath'))" />
<_PackageBuildFile PackagePathWithoutFilename="$([System.IO.Path]::GetDirectoryName('%(Identity)'))" />
<None Include="$(_NETStandardCompatErrorFilePath)"
PackagePath="buildTransitive\%(NETStandardCompatError.Identity)\$(PackageId).targets"
Pack="true" />
<!-- Add the placeholder file to the supported target framework buildTransitive folder, if it's empty.
Because this target uses Item batching, it will run more than once so adding the placeholder to None which would cause a warning.
In order to workaround it, we know this item will contain duplicates, so we will use Distinct() and add it in a target that runs
right after this. -->
<NoneWithDuplicates Include="$(PlaceholderFile)"
PackagePath="$(_NETStandardCompatErrorPlaceholderFilePackagePath)\"
Pack="true"
Condition="'@(_PackageBuildFile)' == '' or
!@(_PackageBuildFile->AnyHaveMetadataValue('PackagePathWithoutFilename', '$(_NETStandardCompatErrorPlaceholderFilePackagePath)'))" />
</ItemGroup>
</Target>
<!-- Add the de-duped placeholder file to the package. -->
<Target Name="_AddPlaceholderFileToNone"
AfterTargets="_AddNETStandardCompatErrorFileForPackaging">
<ItemGroup>
<None Include="@(NoneWithDuplicates->Distinct())" />
</ItemGroup>
</Target>
</Project>

Просмотреть файл

@ -0,0 +1,24 @@
<Project>
<!-- Produce errors if we don't have all the right properties defined -->
<Target Name="_CheckPropsExist" Condition="'$(Stage)' != ''" BeforeTargets="Build">
<Error Condition="'$(Stage)' != 'dev' AND '$(Stage)' != 'normal' AND '$(Stage)' != 'obsolete'" Text="Stage property must be dev|normal|obsolete" />
<Error Condition="'$(Description)' == ''" Text="Missing Description property." />
<Error Condition="'$(Workstream)' == ''" Text="Missing Workstream property." />
<Error Condition="'$(MinCodeCoverage)' == ''" Text="Missing MinCodeCoverage property." />
<Error Condition="'$(MinMutationScore)' == ''" Text="Missing MinMutationScore property." />
</Target>
<!-- Produce errors if we don't have all the right property values for normal stage -->
<Target Name="_CheckNormalStageProps" Condition="'$(Stage)' == 'normal'" BeforeTargets="Build">
<Error Condition="'$(MinCodeCoverage)' != 'n/a' AND ('$(MinCodeCoverage)' &lt; 85)" Text="MinCodeCoverage property must be >= 85 for normal stage." />
<Error Condition="'$(MinMutationScore)' != 'n/a' AND ('$(MinMutationScore)' &lt; 50)" Text="MinMutationScore property must be >= 50 for normal stage." />
</Target>
<!-- Amend the description based on stage -->
<PropertyGroup>
<Description Condition="'$(Stage)' == 'dev'">DEVELOPMENT BUILD - DO NOT USE IN PRODUCTION - $(Description)</Description>
<Description Condition="'$(Stage)' == 'obsolete'">OBSOLETE PACKAGE - $(Description)</Description>
</PropertyGroup>
</Project>

42
eng/MSBuild/Shared.props Normal file
Просмотреть файл

@ -0,0 +1,42 @@
<Project>
<ItemGroup Condition="'$(InjectSharedThrow)' == 'true'">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\Shared\Throw\*.cs" LinkBase="Shared\Throw" />
</ItemGroup>
<ItemGroup Condition="'$(InjectSharedEmptyCollections)' == 'true'">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\Shared\EmptyCollections\*.cs" LinkBase="Shared\EmptyCollections" />
</ItemGroup>
<ItemGroup Condition="'$(InjectSharedRentedSpan)' == 'true'">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\Shared\RentedSpan\*.cs" LinkBase="Shared\RentedSpan" />
</ItemGroup>
<ItemGroup Condition="'$(InjectSharedNumericExtensions)' == 'true'">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\Shared\NumericExtensions\*.cs" LinkBase="Shared\NumericExtensions" />
</ItemGroup>
<ItemGroup Condition="'$(InjectSharedTextFormatting)' == 'true'">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\Shared\Text.Formatting\*.cs" LinkBase="Shared\Text.Formatting" />
</ItemGroup>
<ItemGroup Condition="'$(InjectSharedDebugger)' == 'true'">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\Shared\Debugger\*.cs" LinkBase="Shared\Debugger" />
</ItemGroup>
<ItemGroup Condition="'$(InjectSharedMemoization)' == 'true'">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\Shared\Memoization\*.cs" LinkBase="Shared\Memoization" />
</ItemGroup>
<ItemGroup Condition="'$(InjectSharedDataValidation)' == 'true'">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\Shared\Data.Validation\*.cs" LinkBase="Shared\Data.Validation" />
</ItemGroup>
<ItemGroup Condition="'$(InjectSharedPools)' == 'true'">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\Shared\Pools\*.cs" LinkBase="Shared\Pools" />
<PackageReference Include="Microsoft.Extensions.ObjectPool" />
</ItemGroup>
<ItemGroup Condition="'$(InjectSharedBufferWriterPool)' == 'true'">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\Shared\BufferWriterPool\*.cs" LinkBase="Shared\Pools" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,31 @@
<Project>
<PropertyGroup Condition="'$(InjectSharedThrow)' == 'true'">
<InjectCallerAttributesOnLegacy Condition="'$(InjectCallerAttributesOnLegacy)' == ''">true</InjectCallerAttributesOnLegacy>
<InjectDiagnosticAttributesOnLegacy Condition="'$(InjectDiagnosticAttributesOnLegacy)' == ''">true</InjectDiagnosticAttributesOnLegacy>
</PropertyGroup>
<PropertyGroup Condition="'$(InjectSharedTextFormatting)' == 'true'">
<InjectSkipLocalsInitAttributeOnLegacy Condition="'$(InjectSkipLocalsInitAttributeOnLegacy)' == ''">true</InjectSkipLocalsInitAttributeOnLegacy>
<InjectStringSyntaxAttributeOnLegacy Condition="'$(InjectStringSyntaxAttributeOnLegacy)' == ''">true</InjectStringSyntaxAttributeOnLegacy>
<InjectSharedStringBuilderExtensions Condition="'$(InjectSharedStringBuilderExtensions)' == ''">true</InjectSharedStringBuilderExtensions>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="'$(InjectSharedDataValidation)' == 'true'">
<InjectCallerAttributesOnLegacy Condition="'$(InjectCallerAttributesOnLegacy)' == ''">true</InjectCallerAttributesOnLegacy>
<InjectTrimAttributesOnLegacy Condition="'$(InjectTrimAttributesOnLegacy)' == ''">true</InjectTrimAttributesOnLegacy>
<InjectDiagnosticAttributesOnLegacy Condition="'$(InjectDiagnosticAttributesOnLegacy)' == ''">true</InjectDiagnosticAttributesOnLegacy>
<InjectSharedThrow Condition="'$(InjectSharedThrow)' == ''">true</InjectSharedThrow>
</PropertyGroup>
<PropertyGroup Condition="'$(InjectSharedBufferWriterPool)' == 'true'">
<InjectSharedPools Condition="'$(InjectSharedPools)' == ''">true</InjectSharedPools>
</PropertyGroup>
<PropertyGroup Condition="'$(InjectSharedPools)' == 'true'">
<InjectCallerAttributesOnLegacy Condition="'$(InjectCallerAttributesOnLegacy)' == ''">true</InjectCallerAttributesOnLegacy>
<InjectSharedThrow Condition="'$(InjectSharedThrow)' == ''">true</InjectSharedThrow>
<InjectDiagnosticAttributesOnLegacy Condition="'$(InjectDiagnosticAttributesOnLegacy)' == ''">true</InjectDiagnosticAttributesOnLegacy>
</PropertyGroup>
</Project>

Двоичные данные
eng/MSSharedLibSN2048.snk Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,15 @@
# PSScriptAnalyzerSettings.psd1
# Settings for PSScriptAnalyzer invocation.
@{
Severity = @('Error', 'Warning')
IncludeRules = 'PSAvoid*'
# Do not analyze the following rules. Use ExcludeRules when you have
# commented out the IncludeRules settings above and want to include all
# the default rules except for those you exclude below.
# Note: if a rule is in both IncludeRules and ExcludeRules, the rule
# will be excluded.
ExcludeRules = @(
'PSUseShouldProcessForStateChangingFunctions',
'PSUseSingularNouns')
}

Просмотреть файл

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Packages used only during build time -->
<ItemGroup>
<PackageVersion Include="FlatSharp.Compiler" Version="6.3.5" />
<PackageVersion Include="Google.Protobuf.Tools" Version="3.21.9" />
<PackageVersion Include="Grpc.Tools" Version="2.45.0" />
<PackageVersion Include="LibGit2Sharp" Version="0.27.0-preview-0175" />
<PackageVersion Include="Microsoft.Build.Framework" Version="17.4.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="7.0.0" />
<PackageVersion Include="Microsoft.M365.Internal.Security.SecurityTooling.SDLToolingConfig" Version="0.8.0" GeneratePathProperty="true" />
<PackageVersion Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.5.22" />
<PackageVersion Include="MSBuild.StructuredLogger" Version="2.1.790" />
<PackageVersion Include="SonarAnalyzer.CSharp" Version="8.52.0.60960" />
<PackageVersion Include="StyleCop.Analyzers.Unstable" Version="1.2.0.435" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Condition="'$(TargetFramework)' == '$(LatestTargetFramework)'">
<PackageVersion Include="Microsoft.Bcl.TimeProvider" Version="$(MicrosoftBclTimeProviderVersion)" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="$(MicrosoftExtensionsConfigurationAbstractionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="$(MicrosoftExtensionsConfigurationAbstractionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="$(MicrosoftExtensionsConfigurationBinderVersion)" />
<PackageVersion Include="Microsoft.Extensions.Configuration.CommandLine" Version="$(MicrosoftExtensionsConfigurationCommandLineVersion)" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="$(MicrosoftExtensionsConfigurationJsonVersion)" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="$(MicrosoftExtensionsConfigurationVersion)" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="$(MicrosoftExtensionsDependencyInjectionAbstractionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="$(MicrosoftExtensionsDependencyInjectionVersion)" />
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions" Version="$(MicrosoftExtensionsDiagnosticsHealthChecksAbstractionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="$(MicrosoftExtensionsDiagnosticsHealthChecksVersion)" />
<PackageVersion Include="Microsoft.Extensions.Features" Version="$(MicrosoftExtensionsFeaturesVersion)" />
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="$(MicrosoftExtensionsHostingAbstractionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="$(MicrosoftExtensionsHostingVersion)" />
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="$(MicrosoftExtensionsHttpPollyVersion)" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="$(MicrosoftExtensionsHttpVersion)" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="$(MicrosoftExtensionsLoggingAbstractionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Logging.Configuration" Version="$(MicrosoftExtensionsLoggingConfigurationVersion)" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsoleVersion)" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsLoggingVersion)" />
<PackageVersion Include="Microsoft.Extensions.ObjectPool" Version="$(MicrosoftExtensionsObjectPoolVersion)" />
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="$(MicrosoftExtensionsOptionsConfigurationExtensionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Options.DataAnnotations" Version="$(MicrosoftExtensionsOptionsDataAnnotationsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="$(MicrosoftExtensionsOptionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Primitives" Version="$(MicrosoftExtensionsPrimitivesVersion)" />
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="$(SystemDiagnosticsDiagnosticSourceVersion)" />
<PackageVersion Include="System.Diagnostics.PerformanceCounter" Version="$(SystemDiagnosticsPerformanceCounterVersion)" />
<PackageVersion Include="System.IO.Hashing" Version="$(SystemIOHashingVersion)" />
<PackageVersion Include="System.Net.Http.Json" Version="$(SystemNetHttpJsonVersion)" />
<PackageVersion Include="System.Text.Json" Version="$(SystemTextJsonVersion)" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Condition="'$(TargetFramework)' == 'net462'">
<PackageVersion Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageVersion Include="Microsoft.AspNetCore.Http.Features" Version="2.2.0" />
<PackageVersion Include="Microsoft.AspNetCore.Routing.Abstractions" Version="2.2.0" />
<PackageVersion Include="Microsoft.AspNetCore.Routing" Version="2.2.2" />
<PackageVersion Include="Microsoft.Bcl.HashCode" Version="1.1.1" />
<PackageVersion Include="Microsoft.Bcl.TimeProvider" Version="$(MicrosoftBclTimeProviderVersion)" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="3.1.22" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="$(MicrosoftExtensionsConfigurationAbstractionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="$(MicrosoftExtensionsConfigurationBinderVersion)" />
<PackageVersion Include="Microsoft.Extensions.Configuration.CommandLine" Version="$(MicrosoftExtensionsConfigurationCommandLineVersion)" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="$(MicrosoftExtensionsConfigurationJsonVersion)" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="$(MicrosoftExtensionsConfigurationVersion)" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="$(MicrosoftExtensionsDependencyInjectionAbstractionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="$(MicrosoftExtensionsDependencyInjectionVersion)" />
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions" Version="2.2.0" />
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="2.2.5" />
<PackageVersion Include="Microsoft.Extensions.Features" Version="6.0.1" />
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="$(MicrosoftExtensionsHostingAbstractionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="$(MicrosoftExtensionsHostingVersion)" />
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="2.2.0" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="2.2.0"/>
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="$(MicrosoftExtensionsLoggingAbstractionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Logging.Configuration" Version="$(MicrosoftExtensionsLoggingConfigurationVersion)" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsoleVersion)" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsLoggingVersion)" />
<PackageVersion Include="Microsoft.Extensions.ObjectPool" Version="$(MicrosoftExtensionsObjectPoolVersion)" />
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="$(MicrosoftExtensionsOptionsConfigurationExtensionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Options.DataAnnotations" Version="$(MicrosoftExtensionsOptionsDataAnnotationsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="$(MicrosoftExtensionsOptionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Primitives" Version="$(MicrosoftExtensionsPrimitivesVersion)" />
<PackageVersion Include="System.Buffers" Version="4.5.1" />
<PackageVersion Include="System.Collections.Immutable" Version="$(SystemCollectionsImmutableVersion)" />
<PackageVersion Include="System.ComponentModel.Annotations" Version="4.7.0" />
<PackageVersion Include="System.Diagnostics.PerformanceCounter" Version="4.7.0" />
<PackageVersion Include="System.Memory" Version="4.5.5" />
<PackageVersion Include="System.Net.Http.Json" Version="3.2.1" />
<PackageVersion Include="System.Net.Http" Version="4.3.4" />
<PackageVersion Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="$(SystemDiagnosticsDiagnosticSourceVersion)" />
<PackageVersion Include="System.Text.Json" Version="$(SystemTextJsonVersion)" />
<PackageVersion Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
<PackageVersion Include="System.ValueTuple" Version="4.5.0" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<PackageVersion Include="Microsoft.Bcl.TimeProvider" Version="$(MicrosoftBclTimeProviderVersion)" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="$(MicrosoftExtensionsConfigurationAbstractionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="$(MicrosoftExtensionsConfigurationBinderVersion)" />
<PackageVersion Include="Microsoft.Extensions.Configuration.CommandLine" Version="$(MicrosoftExtensionsConfigurationCommandLineVersion)" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="$(MicrosoftExtensionsConfigurationJsonVersion)" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="$(MicrosoftExtensionsConfigurationVersion)" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="$(MicrosoftExtensionsDependencyInjectionAbstractionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="$(MicrosoftExtensionsDependencyInjectionVersion)" />
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions" Version="6.0.1" />
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="6.0.1" />
<PackageVersion Include="Microsoft.Extensions.Features" Version="6.0.1" />
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="$(MicrosoftExtensionsHostingAbstractionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="$(MicrosoftExtensionsHostingVersion)" />
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="6.0.1" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="6.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="$(MicrosoftExtensionsLoggingAbstractionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Logging.Configuration" Version="$(MicrosoftExtensionsLoggingConfigurationVersion)" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsoleVersion)" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsLoggingVersion)" />
<PackageVersion Include="Microsoft.Extensions.ObjectPool" Version="$(MicrosoftExtensionsObjectPoolVersion)" />
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="$(MicrosoftExtensionsOptionsConfigurationExtensionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Options.DataAnnotations" Version="$(MicrosoftExtensionsOptionsDataAnnotationsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="$(MicrosoftExtensionsOptionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Primitives" Version="$(MicrosoftExtensionsPrimitivesVersion)" />
<PackageVersion Include="System.Collections.Immutable" Version="$(SystemCollectionsImmutableVersion)" />
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="$(SystemDiagnosticsDiagnosticSourceVersion)" />
<PackageVersion Include="System.Diagnostics.PerformanceCounter" Version="6.0.0" />
<PackageVersion Include="System.Net.Http.Json" Version="6.0.0" />
<PackageVersion Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
<PackageVersion Include="System.Text.Json" Version="$(SystemTextJsonVersion)" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
<PackageVersion Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageVersion Include="Microsoft.AspNetCore.Http.Features" Version="3.1.22" />
<PackageVersion Include="Microsoft.Bcl.TimeProvider" Version="$(MicrosoftBclTimeProviderVersion)" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="3.1.22" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="$(MicrosoftExtensionsConfigurationAbstractionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="$(MicrosoftExtensionsConfigurationBinderVersion)" />
<PackageVersion Include="Microsoft.Extensions.Configuration.CommandLine" Version="$(MicrosoftExtensionsConfigurationCommandLineVersion)" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="$(MicrosoftExtensionsConfigurationJsonVersion)" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="$(MicrosoftExtensionsConfigurationVersion)" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="$(MicrosoftExtensionsDependencyInjectionAbstractionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="$(MicrosoftExtensionsDependencyInjectionVersion)" />
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions" Version="3.1.22" />
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="3.1.22" />
<PackageVersion Include="Microsoft.Extensions.Features" Version="6.0.1" />
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="$(MicrosoftExtensionsHostingAbstractionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="$(MicrosoftExtensionsHostingVersion)" />
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="3.1.22" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="3.1.22"/>
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="$(MicrosoftExtensionsLoggingAbstractionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Logging.Configuration" Version="$(MicrosoftExtensionsLoggingConfigurationVersion)" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsoleVersion)" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsLoggingVersion)" />
<PackageVersion Include="Microsoft.Extensions.ObjectPool" Version="$(MicrosoftExtensionsObjectPoolVersion)" />
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="$(MicrosoftExtensionsOptionsConfigurationExtensionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Options.DataAnnotations" Version="$(MicrosoftExtensionsOptionsDataAnnotationsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="$(MicrosoftExtensionsOptionsVersion)" />
<PackageVersion Include="Microsoft.Extensions.Primitives" Version="$(MicrosoftExtensionsPrimitivesVersion)" />
<PackageVersion Include="System.Collections.Immutable" Version="$(SystemCollectionsImmutableVersion)" />
<PackageVersion Include="System.ComponentModel.Annotations" Version="4.7.0" />
<PackageVersion Include="System.Diagnostics.PerformanceCounter" Version="6.0.0" />
<PackageVersion Include="System.Net.Http.Json" Version="3.2.1" />
<PackageVersion Include="System.Private.Uri" Version="4.3.2" />
<PackageVersion Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="$(SystemDiagnosticsDiagnosticSourceVersion)" />
<PackageVersion Include="System.Text.Json" Version="$(SystemTextJsonVersion)" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<PackageVersion Include="Azure.Core" Version="1.25.0" />
<PackageVersion Include="Azure.Identity" Version="1.7.0" />
<PackageVersion Include="Azure.Security.KeyVault.Certificates" Version="4.4.0" />
<PackageVersion Include="Azure.Security.KeyVault.Keys" Version="4.4.0" />
<PackageVersion Include="Azure.Security.KeyVault.Secrets" Version="4.4.0" />
<PackageVersion Include="Azure.Storage.Queues" Version="12.12.0" />
<PackageVersion Include="Google.Protobuf" Version="3.18.3" />
<PackageVersion Include="Grpc.AspNetCore" Version="2.41.0" />
<PackageVersion Include="Grpc.Net.Client" Version="2.41.0" />
<PackageVersion Include="Microsoft.Azure.Cosmos" Version="3.28.0-preview"/>
<PackageVersion Include="Microsoft.Azure.KeyVault.AzureServiceDeploy" Version="3.0.0" />
<PackageVersion Include="Microsoft.Azure.Services.AppAuthentication" Version="1.6.1" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="4.0.1" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.0.1" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.0.1" />
<PackageVersion Include="Microsoft.CodeAnalysis" Version="4.0.1" />
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="2.2.0" />
<PackageVersion Include="Microsoft.Net.Http.Headers" Version="2.2.8" />
<PackageVersion Include="Microsoft.ServiceFabric.Services" Version="4.2.434" />
<PackageVersion Include="Microsoft.ServiceFabric" Version="[7.2.434, )" />
<PackageVersion Include="Microsoft.WindowsAzure.ServiceRuntime" Version="3.0.1382.30" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.1" />
<PackageVersion Include="OpenTelemetry.Api" Version="1.4.0" />
<PackageVersion Include="OpenTelemetry.Exporter.Geneva" Version="1.4.0" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.4.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.0.0-rc9.14" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.0.0-rc9.14" />
<PackageVersion Include="OpenTelemetry" Version="1.4.0" />
<PackageVersion Include="Polly.Contrib.Simmy" Version="0.3.0" />
<PackageVersion Include="Polly.Contrib.WaitAndRetry" Version="1.1.1" />
<PackageVersion Include="Polly" Version="7.2.3" />
<PackageVersion Include="protobuf-net" Version="3.0.101" />
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
<PackageVersion Include="System.CommandLine.NamingConventionBinder" Version="2.0.0-beta4.22272.1" />
</ItemGroup>
<Import Project="$(MSBuildThisFileDirectory)\General-net462.props" />
<Import Project="$(MSBuildThisFileDirectory)\General-netcoreapp3.1.props" />
<Import Project="$(MSBuildThisFileDirectory)\General-net6.0.props" />
<Import Project="$(MSBuildThisFileDirectory)\General-latest.props" />
</Project>

Просмотреть файл

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Azure.KeyVault.AzureServiceDeploy" />
<package id="Microsoft.IC3.Auth.BloomFilter.Revocation" />
<package id="Microsoft.IC3.Auth.Seal.Cae.Ipca" />
<package id="Microsoft.IC3.Hosting.CloudServiceLifetime" />
<package id="Microsoft.Identity.ServiceEssentials.Core" />
<package id="Microsoft.Identity.ServiceEssentials.DataContracts.Policy" />
<package id="Microsoft.Identity.ServiceEssentials.DataContracts.RevocationEvents" />
<package id="Microsoft.Identity.ServiceEssentials.Extensions.AspNetCoreMiddleware" />
<package id="Microsoft.IdentityModel.S2S" />
<package id="Microsoft.IdentityModel.S2S.Configuration" />
<package id="Microsoft.IdentityModel.S2S.Extensions.AspNetCore" />
<package id="OpenTelemetry.Exporter.Geneva" />
<package id="SonarAnalyzer.CSharp" />
<package id="Microsoft.CPR.VisualStudio.Analyzers2019" />
<package id="Microsoft.CPR.Logging.Interfaces" />
<package id="Microsoft.CPR.Pacs.Serialization" />
<package id="Microsoft.Internal.Analyzers" />
<package id="Microsoft.Caching.Redis" />
<package id="Microsoft.Cloud.InstrumentationFramework.Metrics.Extensions" />
<package id="OpenTelemetry.Api" />
<package id="AzureThrottle.ClientImpl" />
<package id="AzureThrottle.Client" />
<package id="AzureThrottle.Common" />
<package id="AzureThrottle.Data" />
<package id="Microsoft.AAD.Throttling.Throttle" />
<package id="Microsoft.Cloud.HealthService.Client" />
<package id="Microsoft.Skype.Tools.Monitoring.Geneva.Api" />
</packages>

Просмотреть файл

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="FlatSharp.Runtime" />
<package id="Google.Protobuf" />
<package id="K4os.Compression.LZ4" />
<package id="Polly.Contrib.Simmy" />
<package id="Polly.Contrib.WaitAndRetry" />
<package id="Polly" />
</packages>

Просмотреть файл

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Condition="'$(TargetFramework)' == '$(LatestTargetFramework)'">
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="$(MicrosoftAspNetCoreMvcTestingVersion)" />
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="$(MicrosoftAspNetCoreTestHostVersion)" />
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="$(SystemConfigurationConfigurationManagerVersion)" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Condition="'$(TargetFramework)' == 'net462'">
<PackageVersion Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="2.2.0" />
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="4.7.0" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="6.0.1" />
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="6.0.0" />
</ItemGroup>
</Project>

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше