Merge branch 'master' into merge/release/5.0-preview7-to-master
This commit is contained in:
commit
de034feb98
|
|
@ -433,7 +433,8 @@ stages:
|
|||
jobName: Linux_musl_x64_build
|
||||
jobDisplayName: "Build: Linux Musl x64"
|
||||
agentOs: Linux
|
||||
buildScript: ./dockerbuild.sh alpine
|
||||
container: mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.9-WithNode-0fc54a3-20190918214015
|
||||
buildScript: ./build.sh
|
||||
buildArgs:
|
||||
--arch x64
|
||||
--os-name linux-musl
|
||||
|
|
@ -448,6 +449,7 @@ stages:
|
|||
$(_InternalRuntimeDownloadArgs)
|
||||
installNodeJs: false
|
||||
installJdk: false
|
||||
skipComponentGovernanceDetection: true
|
||||
artifacts:
|
||||
- name: Linux_musl_x64_Logs
|
||||
path: artifacts/log/
|
||||
|
|
@ -466,7 +468,8 @@ stages:
|
|||
jobDisplayName: "Build: Linux Musl ARM64"
|
||||
agentOs: Linux
|
||||
useHostedUbuntu: false
|
||||
buildScript: ./dockerbuild.sh ubuntu-alpine37
|
||||
container: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-16.04-cross-arm64-alpine-20200413125008-406629a
|
||||
buildScript: ./build.sh
|
||||
buildArgs:
|
||||
--arch arm64
|
||||
--os-name linux-musl
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@
|
|||
# Specifies what directory to run build.sh/cmd
|
||||
# buildScript: string
|
||||
# Specifies the build script to run. Defaults to build.sh or build.cmd.
|
||||
|
||||
# skipComponentGovernanceDetection: boolean
|
||||
# Determines if component governance detection can be skipped
|
||||
#
|
||||
# See https://docs.microsoft.com/en-us/vsts/pipelines/yaml-schema for details
|
||||
#
|
||||
|
|
@ -60,6 +61,7 @@ parameters:
|
|||
installJdk: true
|
||||
timeoutInMinutes: 180
|
||||
useHostedUbuntu: true
|
||||
skipComponentGovernanceDetection: false
|
||||
|
||||
# We need longer than the default amount of 5 minutes to upload our logs/artifacts. (We currently take around 5 mins in the best case).
|
||||
# This makes sure we have time to upload everything in the case of a build timeout - really important for investigating a build
|
||||
|
|
@ -114,6 +116,8 @@ jobs:
|
|||
name: NetCoreInternal-Pool
|
||||
# Visual Studio Enterprise - contains some stuff, like SQL Server and IIS Express, that we use for testing
|
||||
queue: BuildPool.Server.Amd64.VS2019
|
||||
${{ if ne(parameters.container, '') }}:
|
||||
container: ${{ parameters.container }}
|
||||
variables:
|
||||
- AgentOsName: ${{ parameters.agentOs }}
|
||||
- ASPNETCORE_TEST_LOG_MAXPATH: "200" # Keep test log file name length low enough for artifact zipping
|
||||
|
|
@ -238,7 +242,7 @@ jobs:
|
|||
continueOnError: true
|
||||
condition: always()
|
||||
|
||||
- ${{ if and(startsWith(parameters.jobDisplayName, 'Build:'), ne(variables['skipComponentGovernanceDetection'], 'true'), notin(variables['Build.Reason'], 'PullRequest')) }}:
|
||||
- ${{ if and(startsWith(parameters.jobDisplayName, 'Build:'), ne(variables['skipComponentGovernanceDetection'], 'true'), ne(parameters.skipComponentGovernanceDetection, 'true'), notin(variables['Build.Reason'], 'PullRequest')) }}:
|
||||
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
|
||||
condition: and(succeeded(), ne(variables['CG_RAN'], 'true'))
|
||||
displayName: 'Component Detection'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,149 @@
|
|||
# We want to run quarantined tests on master as well as on PRs
|
||||
trigger:
|
||||
batch: true
|
||||
branches:
|
||||
include:
|
||||
- master
|
||||
|
||||
schedules:
|
||||
- cron: "0 */4 * * *"
|
||||
displayName: Every 4 hours test run
|
||||
branches:
|
||||
include:
|
||||
- master
|
||||
always: true
|
||||
|
||||
variables:
|
||||
- ${{ if ne(variables['System.TeamProject'], 'internal') }}:
|
||||
- name: _UseHelixOpenQueues
|
||||
value: 'true'
|
||||
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
|
||||
- group: DotNet-HelixApi-Access
|
||||
- name: _UseHelixOpenQueues
|
||||
value: 'false'
|
||||
|
||||
jobs:
|
||||
- template: jobs/default-build.yml
|
||||
parameters:
|
||||
jobName: Helix_quarantined_x64
|
||||
jobDisplayName: 'Tests: Helix'
|
||||
agentOs: Windows
|
||||
timeoutInMinutes: 240
|
||||
steps:
|
||||
# Build the shared framework
|
||||
- script: ./build.cmd -ci -nobl -all -pack -arch x64 /p:ASPNETCORE_TEST_LOG_DIR=artifacts/log
|
||||
displayName: Build shared fx
|
||||
- script: ./build.cmd -ci -nobl -noBuildRepoTasks -restore -noBuild -noBuildNative -projects src/Grpc/**/*.csproj
|
||||
displayName: Restore interop projects
|
||||
- script: ./build.cmd -ci -nobl -noBuildRepoTasks -noRestore -test -all -noBuildJava -noBuildNative
|
||||
-projects eng\helix\helix.proj /p:RunQuarantinedTests=true /p:IsRequiredCheck=true /p:IsHelixJob=true
|
||||
/p:BuildInteropProjects=true /p:RunTemplateTests=true /p:ASPNETCORE_TEST_LOG_DIR=artifacts/log
|
||||
displayName: Run build.cmd helix target
|
||||
continueOnError: true
|
||||
env:
|
||||
HelixApiAccessToken: $(HelixApiAccessToken) # Needed for internal queues
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken) # We need to set this env var to publish helix results to Azure Dev Ops
|
||||
artifacts:
|
||||
- name: Helix_logs
|
||||
path: artifacts/log/
|
||||
publishOnError: true
|
||||
|
||||
- template: jobs/default-build.yml
|
||||
parameters:
|
||||
jobName: Windows_Quarantined_x64
|
||||
jobDisplayName: 'Tests: Windows x64'
|
||||
agentOs: Windows
|
||||
timeoutInMinutes: 240
|
||||
isTestingJob: true
|
||||
steps:
|
||||
- powershell: "& ./build.ps1 -CI -nobl -all -pack -NoBuildJava"
|
||||
displayName: Build
|
||||
# The templates part can be removed when the Blazor Templates run on Helix
|
||||
- script: ./src/ProjectTemplates/build.cmd -ci -nobl -pack -NoRestore -NoBuilddeps "/p:RunTemplateTests=true"
|
||||
displayName: Pack Templates
|
||||
- script: ./build.cmd -ci -nobl -test -NoRestore -NoBuild -NoBuilddeps "/p:RunTemplateTests=true /p:RunQuarantinedTests=true /p:SkipHelixReadyTests=true"
|
||||
displayName: Run Quarantined Tests
|
||||
continueOnError: true
|
||||
- task: PublishTestResults@2
|
||||
displayName: Publish Quarantined Test Results
|
||||
inputs:
|
||||
testResultsFormat: 'xUnit'
|
||||
testResultsFiles: '*.xml'
|
||||
searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)/Quarantined'
|
||||
condition: always()
|
||||
artifacts:
|
||||
- name: Windows_Quarantined_Test_Logs
|
||||
path: artifacts/log/
|
||||
publishOnError: true
|
||||
includeForks: true
|
||||
- name: Windows_Quarantined_Test_Results
|
||||
path: artifacts/TestResults/
|
||||
publishOnError: true
|
||||
includeForks: true
|
||||
|
||||
- template: jobs/default-build.yml
|
||||
parameters:
|
||||
jobName: MacOS_Quarantined_Test
|
||||
jobDisplayName: "Tests: macOS 10.14"
|
||||
agentOs: macOS
|
||||
timeoutInMinutes: 240
|
||||
isTestingJob: true
|
||||
steps:
|
||||
- bash: ./build.sh --all --pack --ci --nobl --no-build-java
|
||||
displayName: Build
|
||||
# The templates part can be removed when the Blazor Templates run on Helix
|
||||
- bash: ./src/ProjectTemplates/build.sh --ci --nobl --pack --no-restore --no-build-deps
|
||||
displayName: Pack Templates (for Template tests)
|
||||
- bash: ./build.sh --no-build --ci --nobl --test -p:RunTemplateTests=true -p:RunQuarantinedTests=true -p:SkipHelixReadyTests=true
|
||||
displayName: Run Quarantined Tests
|
||||
continueOnError: true
|
||||
- task: PublishTestResults@2
|
||||
displayName: Publish Quarantined Test Results
|
||||
inputs:
|
||||
testResultsFormat: 'xUnit'
|
||||
testResultsFiles: '*.xml'
|
||||
searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)/Quarantined'
|
||||
condition: always()
|
||||
artifacts:
|
||||
- name: MacOS_Quarantined_Test_Logs
|
||||
path: artifacts/log/
|
||||
publishOnError: true
|
||||
includeForks: true
|
||||
- name: MacOS_Quarantined_Test_Results
|
||||
path: artifacts/TestResults/
|
||||
publishOnError: true
|
||||
includeForks: true
|
||||
|
||||
- template: jobs/default-build.yml
|
||||
parameters:
|
||||
jobName: Linux_Quarantined_Test
|
||||
jobDisplayName: "Tests: Ubuntu 16.04 x64"
|
||||
agentOs: Linux
|
||||
timeoutInMinutes: 240
|
||||
isTestingJob: true
|
||||
useHostedUbuntu: false
|
||||
steps:
|
||||
- bash: ./build.sh --all --pack --ci --nobl --no-build-java
|
||||
displayName: Build
|
||||
# The templates part can be removed when the Blazor Templates run on Helix
|
||||
- bash: ./src/ProjectTemplates/build.sh --ci --nobl --pack --no-restore --no-build-deps
|
||||
displayName: Pack Templates (for Template tests)
|
||||
- bash: ./build.sh --no-build --ci --nobl --test -p:RunTemplateTests=true -p:RunQuarantinedTests=true -p:SkipHelixReadyTests=true
|
||||
displayName: Run Quarantined Tests
|
||||
continueOnError: true
|
||||
- task: PublishTestResults@2
|
||||
displayName: Publish Quarantined Test Results
|
||||
inputs:
|
||||
testResultsFormat: 'xUnit'
|
||||
testResultsFiles: '*.xml'
|
||||
searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)/Quarantined'
|
||||
condition: always()
|
||||
artifacts:
|
||||
- name: Linux_Quarantined_Test_Logs
|
||||
path: artifacts/log/
|
||||
publishOnError: true
|
||||
includeForks: true
|
||||
- name: Linux_Quarantined_Test_Results
|
||||
path: artifacts/TestResults/
|
||||
publishOnError: true
|
||||
includeForks: true
|
||||
|
|
@ -1,13 +1,10 @@
|
|||
# We want to run quarantined tests on master as well as on PRs
|
||||
trigger:
|
||||
batch: true
|
||||
branches:
|
||||
include:
|
||||
- master
|
||||
# We only want to run quarantined tests on master
|
||||
pr: none
|
||||
trigger: none
|
||||
|
||||
schedules:
|
||||
- cron: "0 */4 * * *"
|
||||
displayName: Every 4 hours test run
|
||||
- cron: "0 18 * * *"
|
||||
displayName: Run tests once a day at 11 PM
|
||||
branches:
|
||||
include:
|
||||
- master
|
||||
|
|
@ -28,7 +25,7 @@ jobs:
|
|||
jobName: Helix_quarantined_x64
|
||||
jobDisplayName: 'Tests: Helix'
|
||||
agentOs: Windows
|
||||
timeoutInMinutes: 180
|
||||
timeoutInMinutes: 480
|
||||
steps:
|
||||
# Build the shared framework
|
||||
- script: ./build.cmd -ci -nobl -all -pack -arch x64 /p:ASPNETCORE_TEST_LOG_DIR=artifacts/log
|
||||
|
|
@ -36,7 +33,7 @@ jobs:
|
|||
- script: ./build.cmd -ci -nobl -noBuildRepoTasks -restore -noBuild -noBuildNative -projects src/Grpc/**/*.csproj
|
||||
displayName: Restore interop projects
|
||||
- script: ./build.cmd -ci -nobl -noBuildRepoTasks -noRestore -test -all -noBuildJava -noBuildNative
|
||||
-projects eng\helix\helix.proj /p:RunQuarantinedTests=true /p:IsRequiredCheck=true /p:IsHelixJob=true
|
||||
-projects eng\helix\helix.proj /p:IsHelixDaily=true /p:RunQuarantinedTests=true /p:IsRequiredCheck=true /p:IsHelixJob=true
|
||||
/p:BuildInteropProjects=true /p:RunTemplateTests=true /p:ASPNETCORE_TEST_LOG_DIR=artifacts/log
|
||||
displayName: Run build.cmd helix target
|
||||
continueOnError: true
|
||||
|
|
@ -48,102 +45,27 @@ jobs:
|
|||
path: artifacts/log/
|
||||
publishOnError: true
|
||||
|
||||
# Helix ARM64
|
||||
- template: jobs/default-build.yml
|
||||
parameters:
|
||||
jobName: Windows_Quarantined_x64
|
||||
jobDisplayName: 'Tests: Windows x64'
|
||||
agentOs: Windows
|
||||
timeoutInMinutes: 180
|
||||
isTestingJob: true
|
||||
steps:
|
||||
- powershell: "& ./build.ps1 -CI -nobl -all -pack -NoBuildJava"
|
||||
displayName: Build
|
||||
# The templates part can be removed when the Blazor Templates run on Helix
|
||||
- script: ./src/ProjectTemplates/build.cmd -ci -nobl -pack -NoRestore -NoBuilddeps "/p:RunTemplateTests=true"
|
||||
displayName: Pack Templates
|
||||
- script: ./build.cmd -ci -nobl -test -NoRestore -NoBuild -NoBuilddeps "/p:RunTemplateTests=true /p:RunQuarantinedTests=true /p:SkipHelixReadyTests=true"
|
||||
displayName: Run Quarantined Tests
|
||||
continueOnError: true
|
||||
- task: PublishTestResults@2
|
||||
displayName: Publish Quarantined Test Results
|
||||
inputs:
|
||||
testResultsFormat: 'xUnit'
|
||||
testResultsFiles: '*.xml'
|
||||
searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)/Quarantined'
|
||||
condition: always()
|
||||
artifacts:
|
||||
- name: Windows_Quarantined_Test_Logs
|
||||
path: artifacts/log/
|
||||
publishOnError: true
|
||||
includeForks: true
|
||||
- name: Windows_Quarantined_Test_Results
|
||||
path: artifacts/TestResults/
|
||||
publishOnError: true
|
||||
includeForks: true
|
||||
|
||||
- template: jobs/default-build.yml
|
||||
parameters:
|
||||
jobName: MacOS_Quarantined_Test
|
||||
jobDisplayName: "Tests: macOS 10.14"
|
||||
agentOs: macOS
|
||||
timeoutInMinutes: 180
|
||||
isTestingJob: true
|
||||
steps:
|
||||
- bash: ./build.sh --all --pack --ci --nobl --no-build-java
|
||||
displayName: Build
|
||||
# The templates part can be removed when the Blazor Templates run on Helix
|
||||
- bash: ./src/ProjectTemplates/build.sh --ci --nobl --pack --no-restore --no-build-deps
|
||||
displayName: Pack Templates (for Template tests)
|
||||
- bash: ./build.sh --no-build --ci --nobl --test -p:RunTemplateTests=true -p:RunQuarantinedTests=true -p:SkipHelixReadyTests=true
|
||||
displayName: Run Quarantined Tests
|
||||
continueOnError: true
|
||||
- task: PublishTestResults@2
|
||||
displayName: Publish Quarantined Test Results
|
||||
inputs:
|
||||
testResultsFormat: 'xUnit'
|
||||
testResultsFiles: '*.xml'
|
||||
searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)/Quarantined'
|
||||
condition: always()
|
||||
artifacts:
|
||||
- name: MacOS_Quarantined_Test_Logs
|
||||
path: artifacts/log/
|
||||
publishOnError: true
|
||||
includeForks: true
|
||||
- name: MacOS_Quarantined_Test_Results
|
||||
path: artifacts/TestResults/
|
||||
publishOnError: true
|
||||
includeForks: true
|
||||
|
||||
- template: jobs/default-build.yml
|
||||
parameters:
|
||||
jobName: Linux_Quarantined_Test
|
||||
jobDisplayName: "Tests: Ubuntu 16.04 x64"
|
||||
jobName: Helix_quarantined_arm64
|
||||
jobDisplayName: "Tests: Helix ARM64"
|
||||
agentOs: Linux
|
||||
timeoutInMinutes: 180
|
||||
isTestingJob: true
|
||||
useHostedUbuntu: false
|
||||
timeoutInMinutes: 480
|
||||
steps:
|
||||
- bash: ./build.sh --all --pack --ci --nobl --no-build-java
|
||||
displayName: Build
|
||||
# The templates part can be removed when the Blazor Templates run on Helix
|
||||
- bash: ./src/ProjectTemplates/build.sh --ci --nobl --pack --no-restore --no-build-deps
|
||||
displayName: Pack Templates (for Template tests)
|
||||
- bash: ./build.sh --no-build --ci --nobl --test -p:RunTemplateTests=true -p:RunQuarantinedTests=true -p:SkipHelixReadyTests=true
|
||||
displayName: Run Quarantined Tests
|
||||
- script: ./restore.sh -ci -nobl
|
||||
displayName: Restore
|
||||
- script: ./build.sh --ci --nobl --noBuildRepoTasks --arch arm64 -test --no-build-nodejs --all --projects
|
||||
$(Build.SourcesDirectory)/eng/helix/helix.proj /p:IsHelixJob=true /p:IsHelixDaily=true /p:RunQuarantinedTests=true
|
||||
/p:ASPNETCORE_TEST_LOG_DIR=artifacts/log
|
||||
displayName: Run build.sh helix arm64 target
|
||||
continueOnError: true
|
||||
- task: PublishTestResults@2
|
||||
displayName: Publish Quarantined Test Results
|
||||
inputs:
|
||||
testResultsFormat: 'xUnit'
|
||||
testResultsFiles: '*.xml'
|
||||
searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)/Quarantined'
|
||||
condition: always()
|
||||
env:
|
||||
HelixApiAccessToken: $(HelixApiAccessToken) # Needed for internal queues
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken) # We need to set this env var to publish helix results to Azure Dev Ops
|
||||
installNodeJs: false
|
||||
artifacts:
|
||||
- name: Linux_Quarantined_Test_Logs
|
||||
- name: Helix_arm64_logs
|
||||
path: artifacts/log/
|
||||
publishOnError: true
|
||||
includeForks: true
|
||||
- name: Linux_Quarantined_Test_Results
|
||||
path: artifacts/TestResults/
|
||||
publishOnError: true
|
||||
includeForks: true
|
||||
|
|
|
|||
|
|
@ -9,14 +9,16 @@
|
|||
/eng/common/ @dotnet-maestro-bot
|
||||
/eng/Versions.props @dotnet-maestro-bot @dougbu
|
||||
/eng/Version.Details.xml @dotnet-maestro-bot @dougbu
|
||||
/src/Components/ @SteveSandersonMS
|
||||
/src/Components/ @SteveSandersonMS @aspnet-blazor-eng
|
||||
/src/DefaultBuilder/ @tratcher
|
||||
/src/Hosting/ @tratcher
|
||||
/src/Http/ @tratcher @jkotalik
|
||||
/src/Middleware/ @tratcher
|
||||
/src/Middleware/HttpsPolicy/ @jkotalik
|
||||
/src/Middleware/Rewrite/ @jkotalik
|
||||
# /src/ProjectTemplates/ @ryanbrandenburg
|
||||
# /src/ProjectTemplates/ @ryanbrandenburg
|
||||
/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/ @aspnet-blazor-eng
|
||||
/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/ @aspnet-blazor-eng
|
||||
/src/Security/ @tratcher
|
||||
/src/Servers/ @tratcher @jkotalik @halter73
|
||||
/src/Shared/runtime/ @dotnet/http
|
||||
|
|
|
|||
|
|
@ -68,6 +68,8 @@ To update an existing copy, run:
|
|||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
**NOTE** some ISPs have been know to use web filtering software that has caused issues with git repository cloning, if you experience issues cloning this repo please review <https://help.github.com/en/github/authenticating-to-github/using-ssh-over-the-https-port>
|
||||
|
||||
## Building in Visual Studio
|
||||
|
||||
Before opening our .sln files in Visual Studio or VS Code, you need to perform the following actions.
|
||||
|
|
@ -228,6 +230,16 @@ TargetOsName | The base runtime identifier to build for (win, linux,
|
|||
After building ASP.NET Core from source, you will need to install and use your local version of ASP.NET Core.
|
||||
See ["Artifacts"](./Artifacts.md) for more explanation of the different folders produced by a build.
|
||||
|
||||
Building installers does not run as part of `build.cmd` run without parameters, so you should opt-in for building them:
|
||||
|
||||
```ps1
|
||||
.\build.cmd -all -pack -arch x64
|
||||
.\build.cmd -all -pack -arch x86 -noBuildJava
|
||||
.\build.cmd -buildInstallers
|
||||
```
|
||||
|
||||
*Note*: Additional build steps listed above aren't necessary on Linux or macOS.
|
||||
|
||||
* Run the installers produced in `artifacts/installers/{Debug, Release}/` for your platform.
|
||||
* Add a NuGet.Config to your project directory with the following content:
|
||||
|
||||
|
|
|
|||
|
|
@ -20,12 +20,23 @@ This will restore, and then publish all the test project including some bootstra
|
|||
|
||||
- Required queues: Windows10, OSX, Ubuntu1604
|
||||
- Full queue matrix: Windows[7, 81, 10], Ubuntu[1604, 1804, 2004], Centos7, Debian[8,9], Redhat7, Fedora28, Arm64 (Win10, Debian9)
|
||||
- The queues are defined in [Helix.Common.props](https://github.com/dotnet/aspnetcore/blob/master/eng/targets/Helix.Common.props)
|
||||
|
||||
aspnetcore-ci runs non quarantined tests against the required helix queues as a required PR check and all builds on all branches.
|
||||
[aspnetcore-ci](https://dev.azure.com/dnceng/public/_build?definitionId=278) runs non quarantined tests against the required helix queues as a required PR check and all builds on all branches.
|
||||
|
||||
aspnetcore-quarantined-tests runs only quarantined tests against the required queues only on master every 4 hours.
|
||||
[aspnetcore-helix-matrix](https://dev.azure.com/dnceng/public/_build?definitionId=837) runs non quarantined tests against all queues twice a day only on public master.
|
||||
|
||||
[aspnetcore-quarantined-pr](https://dev.azure.com/dnceng/public/_build?definitionId=869) runs only quarantined tests against the required queues on PRs and on master every 4 hours.
|
||||
|
||||
[aspnetcore-quarantined-tests](https://dev.azure.com/dnceng/public/_build?definitionId=331) runs only quarantined tests against all queues only on public master once a day at 11 PM.
|
||||
|
||||
You can always manually queue pipeline runs by clicking on the link to the pipeline -> Run Pipeline -> select your branch/tag and commit
|
||||
|
||||
## Checkin process expectations
|
||||
|
||||
- The normal PR process has aspnetcore-ci will ensure that the required queues are green.
|
||||
- If your changes are likely to have cross platform impact that would affect more than the required queues, you should kick off a manual aspnetcore-helix-matrix pipeline run against your branch before merging your PR. Even though aspnetcore-helix-matrix is not a required checkin gate, if your changes break this pipeline, you must either immediately revert your changes, or quarantine the test, its never ok to leave this pipeline in a broken state.
|
||||
|
||||
aspnetcore-helix-matrix runs non quarantined tests against all queues twice a day only on public master.
|
||||
|
||||
## How do I look at the results of a helix run on Azure Pipelines?
|
||||
|
||||
|
|
|
|||
|
|
@ -3,3 +3,9 @@ Contributor documentation
|
|||
|
||||
The primary audience for documentation in this folder is contributors to ASP.NET Core.
|
||||
If you are looking for documentation on how to *use* ASP.NET Core, go to <https://docs.asp.net>.
|
||||
|
||||
# ASP.NET Core developer workflow
|
||||
|
||||
- [Building from source](BuildFromSource.md)
|
||||
- [Troubleshooting build errors](BuildErrors.md)
|
||||
- [Artifacts structure](Artifacts.md)
|
||||
|
|
|
|||
|
|
@ -67,7 +67,6 @@
|
|||
<ProjectReferenceProvider Include="Microsoft.JSInterop.WebAssembly" ProjectPath="$(RepoRoot)src\Components\WebAssembly\JSInterop\src\Microsoft.JSInterop.WebAssembly.csproj" />
|
||||
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Components.WebAssembly.Server" ProjectPath="$(RepoRoot)src\Components\WebAssembly\Server\src\Microsoft.AspNetCore.Components.WebAssembly.Server.csproj" />
|
||||
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" ProjectPath="$(RepoRoot)src\Components\WebAssembly\WebAssembly.Authentication\src\Microsoft.AspNetCore.Components.WebAssembly.Authentication.csproj" />
|
||||
<ProjectReferenceProvider Include="System.Net.Http.WebAssemblyHttpHandler" ProjectPath="$(RepoRoot)src\Components\WebAssembly\WebAssemblyHttpHandler\src\Microsoft.AspNetCore.Components.WebAssembly.HttpHandler.csproj" />
|
||||
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Components.WebAssembly" ProjectPath="$(RepoRoot)src\Components\WebAssembly\WebAssembly\src\Microsoft.AspNetCore.Components.WebAssembly.csproj" />
|
||||
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Testing" ProjectPath="$(RepoRoot)src\Testing\src\Microsoft.AspNetCore.Testing.csproj" />
|
||||
<ProjectReferenceProvider Include="Microsoft.AspNetCore" ProjectPath="$(RepoRoot)src\DefaultBuilder\src\Microsoft.AspNetCore.csproj" RefProjectPath="$(RepoRoot)src\DefaultBuilder\ref\Microsoft.AspNetCore.csproj" />
|
||||
|
|
|
|||
|
|
@ -13,288 +13,288 @@
|
|||
<Uri>https://github.com/dotnet/blazor</Uri>
|
||||
<Sha>cc449601d638ffaab58ae9487f0fd010bb178a12</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="dotnet-ef" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="dotnet-ef" Version="5.0.0-preview.8.20353.5">
|
||||
<Uri>https://github.com/dotnet/efcore</Uri>
|
||||
<Sha>0f2b5023539eb0c5a4fc565af7e59b95c252529f</Sha>
|
||||
<Sha>dff6a1abc282bb642042b4fe3a643f5b586bcf03</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore.InMemory" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore.InMemory" Version="5.0.0-preview.8.20353.5">
|
||||
<Uri>https://github.com/dotnet/efcore</Uri>
|
||||
<Sha>0f2b5023539eb0c5a4fc565af7e59b95c252529f</Sha>
|
||||
<Sha>dff6a1abc282bb642042b4fe3a643f5b586bcf03</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore.Relational" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore.Relational" Version="5.0.0-preview.8.20353.5">
|
||||
<Uri>https://github.com/dotnet/efcore</Uri>
|
||||
<Sha>0f2b5023539eb0c5a4fc565af7e59b95c252529f</Sha>
|
||||
<Sha>dff6a1abc282bb642042b4fe3a643f5b586bcf03</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.0-preview.8.20353.5">
|
||||
<Uri>https://github.com/dotnet/efcore</Uri>
|
||||
<Sha>0f2b5023539eb0c5a4fc565af7e59b95c252529f</Sha>
|
||||
<Sha>dff6a1abc282bb642042b4fe3a643f5b586bcf03</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.0-preview.8.20353.5">
|
||||
<Uri>https://github.com/dotnet/efcore</Uri>
|
||||
<Sha>0f2b5023539eb0c5a4fc565af7e59b95c252529f</Sha>
|
||||
<Sha>dff6a1abc282bb642042b4fe3a643f5b586bcf03</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore.Tools" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore.Tools" Version="5.0.0-preview.8.20353.5">
|
||||
<Uri>https://github.com/dotnet/efcore</Uri>
|
||||
<Sha>0f2b5023539eb0c5a4fc565af7e59b95c252529f</Sha>
|
||||
<Sha>dff6a1abc282bb642042b4fe3a643f5b586bcf03</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore" Version="5.0.0-preview.8.20353.5">
|
||||
<Uri>https://github.com/dotnet/efcore</Uri>
|
||||
<Sha>0f2b5023539eb0c5a4fc565af7e59b95c252529f</Sha>
|
||||
<Sha>dff6a1abc282bb642042b4fe3a643f5b586bcf03</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Caching.Abstractions" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Caching.Abstractions" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Caching.Memory" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Caching.Memory" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Binder" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Binder" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.CommandLine" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.CommandLine" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.FileExtensions" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.FileExtensions" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Ini" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Ini" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Json" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Json" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.UserSecrets" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.UserSecrets" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Xml" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Xml" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.DependencyInjection" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.DependencyInjection" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.FileProviders.Abstractions" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.FileProviders.Abstractions" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.FileProviders.Composite" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.FileProviders.Composite" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.FileProviders.Physical" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.FileProviders.Physical" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.FileSystemGlobbing" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.FileSystemGlobbing" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.HostFactoryResolver.Sources" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.HostFactoryResolver.Sources" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Hosting" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Hosting" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Http" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Http" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Configuration" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Configuration" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Console" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Console" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Debug" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Debug" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging.EventSource" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Logging.EventSource" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging.EventLog" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Logging.EventLog" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging.TraceSource" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Logging.TraceSource" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Logging" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Options.DataAnnotations" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Options.DataAnnotations" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Options" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Options" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Primitives" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Primitives" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Internal.Transport" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.Internal.Transport" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Win32.Registry" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Win32.Registry" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Win32.SystemEvents" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Win32.SystemEvents" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.ComponentModel.Annotations" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="System.ComponentModel.Annotations" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Diagnostics.DiagnosticSource" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="System.Diagnostics.DiagnosticSource" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Diagnostics.EventLog" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="System.Diagnostics.EventLog" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Drawing.Common" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="System.Drawing.Common" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.IO.Pipelines" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="System.IO.Pipelines" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Net.Http.Json" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="System.Net.Http.Json" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Net.Http.WinHttpHandler" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="System.Net.Http.WinHttpHandler" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Net.WebSockets.WebSocketProtocol" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="System.Net.WebSockets.WebSocketProtocol" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Reflection.Metadata" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="System.Reflection.Metadata" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Runtime.CompilerServices.Unsafe" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="System.Runtime.CompilerServices.Unsafe" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Security.Cryptography.Cng" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="System.Security.Cryptography.Cng" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Security.Cryptography.Pkcs" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="System.Security.Cryptography.Pkcs" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Security.Cryptography.Xml" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="System.Security.Cryptography.Xml" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Security.Permissions" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="System.Security.Permissions" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Security.Principal.Windows" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="System.Security.Principal.Windows" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.ServiceProcess.ServiceController" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="System.ServiceProcess.ServiceController" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Text.Encodings.Web" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="System.Text.Encodings.Web" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Text.Json" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="System.Text.Json" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Threading.Channels" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="System.Threading.Channels" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Windows.Extensions" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="System.Windows.Extensions" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.DependencyModel" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.Extensions.DependencyModel" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.NETCore.App.Ref" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.NETCore.App.Ref" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<!--
|
||||
Win-x64 is used here because we have picked an arbitrary runtime identifier to flow the version of the latest NETCore.App runtime.
|
||||
All Runtime.$rid packages should have the same version.
|
||||
-->
|
||||
<Dependency Name="Microsoft.NETCore.App.Runtime.win-x64" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.NETCore.App.Runtime.win-x64" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.NETCore.App.Internal" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.NETCore.App.Internal" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
</ProductDependencies>
|
||||
<ToolsetDependencies>
|
||||
<!-- Listed explicitly to workaround https://github.com/dotnet/cli/issues/10528 -->
|
||||
<Dependency Name="Microsoft.NETCore.Platforms" Version="5.0.0-preview.7.20326.1">
|
||||
<Dependency Name="Microsoft.NETCore.Platforms" Version="5.0.0-preview.8.20352.6">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
||||
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.GenAPI" Version="5.0.0-beta.20316.1">
|
||||
<Uri>https://github.com/dotnet/arcade</Uri>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
<AspNetCoreMajorVersion>5</AspNetCoreMajorVersion>
|
||||
<AspNetCoreMinorVersion>0</AspNetCoreMinorVersion>
|
||||
<AspNetCorePatchVersion>0</AspNetCorePatchVersion>
|
||||
<PreReleaseVersionIteration>7</PreReleaseVersionIteration>
|
||||
<PreReleaseVersionIteration>8</PreReleaseVersionIteration>
|
||||
<!--
|
||||
When StabilizePackageVersion is set to 'true', this branch will produce stable outputs for 'Shipping' packages
|
||||
-->
|
||||
|
|
@ -66,79 +66,79 @@
|
|||
<!-- Packages from dotnet/roslyn -->
|
||||
<MicrosoftNetCompilersToolsetPackageVersion>3.7.0-4.20319.6</MicrosoftNetCompilersToolsetPackageVersion>
|
||||
<!-- Packages from dotnet/runtime -->
|
||||
<MicrosoftExtensionsDependencyModelPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsDependencyModelPackageVersion>
|
||||
<MicrosoftNETCoreAppInternalPackageVersion>5.0.0-preview.7.20326.1</MicrosoftNETCoreAppInternalPackageVersion>
|
||||
<MicrosoftNETCoreAppRefPackageVersion>5.0.0-preview.7.20326.1</MicrosoftNETCoreAppRefPackageVersion>
|
||||
<MicrosoftNETCoreAppRuntimewinx64PackageVersion>5.0.0-preview.7.20326.1</MicrosoftNETCoreAppRuntimewinx64PackageVersion>
|
||||
<MicrosoftWin32RegistryPackageVersion>5.0.0-preview.7.20326.1</MicrosoftWin32RegistryPackageVersion>
|
||||
<MicrosoftWin32SystemEventsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftWin32SystemEventsPackageVersion>
|
||||
<MicrosoftExtensionsCachingAbstractionsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsCachingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsCachingMemoryPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsCachingMemoryPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationAbstractionsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsConfigurationAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationBinderPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsConfigurationBinderPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationCommandLinePackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsConfigurationCommandLinePackageVersion>
|
||||
<MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationIniPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsConfigurationIniPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationJsonPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsConfigurationJsonPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsConfigurationPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationUserSecretsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsConfigurationUserSecretsPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationXmlPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsConfigurationXmlPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsDependencyInjectionPackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersCompositePackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsFileProvidersCompositePackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersPhysicalPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsFileProvidersPhysicalPackageVersion>
|
||||
<MicrosoftExtensionsFileSystemGlobbingPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsFileSystemGlobbingPackageVersion>
|
||||
<MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion>
|
||||
<MicrosoftExtensionsHostingAbstractionsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsHostingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsHostingPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsHostingPackageVersion>
|
||||
<MicrosoftExtensionsHttpPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsHttpPackageVersion>
|
||||
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsLoggingConfigurationPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsLoggingConfigurationPackageVersion>
|
||||
<MicrosoftExtensionsLoggingConsolePackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsLoggingConsolePackageVersion>
|
||||
<MicrosoftExtensionsLoggingDebugPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsLoggingDebugPackageVersion>
|
||||
<MicrosoftExtensionsLoggingEventSourcePackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsLoggingEventSourcePackageVersion>
|
||||
<MicrosoftExtensionsLoggingEventLogPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsLoggingEventLogPackageVersion>
|
||||
<MicrosoftExtensionsLoggingPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsLoggingPackageVersion>
|
||||
<MicrosoftExtensionsLoggingTraceSourcePackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsLoggingTraceSourcePackageVersion>
|
||||
<MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>
|
||||
<MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>
|
||||
<MicrosoftExtensionsOptionsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsOptionsPackageVersion>
|
||||
<MicrosoftExtensionsPrimitivesPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsPrimitivesPackageVersion>
|
||||
<MicrosoftExtensionsInternalTransportPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsInternalTransportPackageVersion>
|
||||
<SystemComponentModelAnnotationsPackageVersion>5.0.0-preview.7.20326.1</SystemComponentModelAnnotationsPackageVersion>
|
||||
<SystemDiagnosticsDiagnosticSourcePackageVersion>5.0.0-preview.7.20326.1</SystemDiagnosticsDiagnosticSourcePackageVersion>
|
||||
<SystemDiagnosticsEventLogPackageVersion>5.0.0-preview.7.20326.1</SystemDiagnosticsEventLogPackageVersion>
|
||||
<SystemDrawingCommonPackageVersion>5.0.0-preview.7.20326.1</SystemDrawingCommonPackageVersion>
|
||||
<SystemIOPipelinesPackageVersion>5.0.0-preview.7.20326.1</SystemIOPipelinesPackageVersion>
|
||||
<SystemNetHttpJsonPackageVersion>5.0.0-preview.7.20326.1</SystemNetHttpJsonPackageVersion>
|
||||
<SystemNetHttpWinHttpHandlerPackageVersion>5.0.0-preview.7.20326.1</SystemNetHttpWinHttpHandlerPackageVersion>
|
||||
<SystemNetWebSocketsWebSocketProtocolPackageVersion>5.0.0-preview.7.20326.1</SystemNetWebSocketsWebSocketProtocolPackageVersion>
|
||||
<SystemReflectionMetadataPackageVersion>5.0.0-preview.7.20326.1</SystemReflectionMetadataPackageVersion>
|
||||
<SystemRuntimeCompilerServicesUnsafePackageVersion>5.0.0-preview.7.20326.1</SystemRuntimeCompilerServicesUnsafePackageVersion>
|
||||
<SystemSecurityCryptographyCngPackageVersion>5.0.0-preview.7.20326.1</SystemSecurityCryptographyCngPackageVersion>
|
||||
<SystemSecurityCryptographyPkcsPackageVersion>5.0.0-preview.7.20326.1</SystemSecurityCryptographyPkcsPackageVersion>
|
||||
<SystemSecurityCryptographyXmlPackageVersion>5.0.0-preview.7.20326.1</SystemSecurityCryptographyXmlPackageVersion>
|
||||
<SystemSecurityPermissionsPackageVersion>5.0.0-preview.7.20326.1</SystemSecurityPermissionsPackageVersion>
|
||||
<SystemSecurityPrincipalWindowsPackageVersion>5.0.0-preview.7.20326.1</SystemSecurityPrincipalWindowsPackageVersion>
|
||||
<SystemServiceProcessServiceControllerPackageVersion>5.0.0-preview.7.20326.1</SystemServiceProcessServiceControllerPackageVersion>
|
||||
<SystemTextEncodingsWebPackageVersion>5.0.0-preview.7.20326.1</SystemTextEncodingsWebPackageVersion>
|
||||
<SystemTextJsonPackageVersion>5.0.0-preview.7.20326.1</SystemTextJsonPackageVersion>
|
||||
<SystemThreadingChannelsPackageVersion>5.0.0-preview.7.20326.1</SystemThreadingChannelsPackageVersion>
|
||||
<SystemWindowsExtensionsPackageVersion>5.0.0-preview.7.20326.1</SystemWindowsExtensionsPackageVersion>
|
||||
<MicrosoftExtensionsDependencyModelPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsDependencyModelPackageVersion>
|
||||
<MicrosoftNETCoreAppInternalPackageVersion>5.0.0-preview.8.20352.6</MicrosoftNETCoreAppInternalPackageVersion>
|
||||
<MicrosoftNETCoreAppRefPackageVersion>5.0.0-preview.8.20352.6</MicrosoftNETCoreAppRefPackageVersion>
|
||||
<MicrosoftNETCoreAppRuntimewinx64PackageVersion>5.0.0-preview.8.20352.6</MicrosoftNETCoreAppRuntimewinx64PackageVersion>
|
||||
<MicrosoftWin32RegistryPackageVersion>5.0.0-preview.8.20352.6</MicrosoftWin32RegistryPackageVersion>
|
||||
<MicrosoftWin32SystemEventsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftWin32SystemEventsPackageVersion>
|
||||
<MicrosoftExtensionsCachingAbstractionsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsCachingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsCachingMemoryPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsCachingMemoryPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationAbstractionsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsConfigurationAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationBinderPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsConfigurationBinderPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationCommandLinePackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsConfigurationCommandLinePackageVersion>
|
||||
<MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationIniPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsConfigurationIniPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationJsonPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsConfigurationJsonPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsConfigurationPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationUserSecretsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsConfigurationUserSecretsPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationXmlPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsConfigurationXmlPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsDependencyInjectionPackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersCompositePackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsFileProvidersCompositePackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersPhysicalPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsFileProvidersPhysicalPackageVersion>
|
||||
<MicrosoftExtensionsFileSystemGlobbingPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsFileSystemGlobbingPackageVersion>
|
||||
<MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion>
|
||||
<MicrosoftExtensionsHostingAbstractionsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsHostingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsHostingPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsHostingPackageVersion>
|
||||
<MicrosoftExtensionsHttpPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsHttpPackageVersion>
|
||||
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsLoggingConfigurationPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsLoggingConfigurationPackageVersion>
|
||||
<MicrosoftExtensionsLoggingConsolePackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsLoggingConsolePackageVersion>
|
||||
<MicrosoftExtensionsLoggingDebugPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsLoggingDebugPackageVersion>
|
||||
<MicrosoftExtensionsLoggingEventSourcePackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsLoggingEventSourcePackageVersion>
|
||||
<MicrosoftExtensionsLoggingEventLogPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsLoggingEventLogPackageVersion>
|
||||
<MicrosoftExtensionsLoggingPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsLoggingPackageVersion>
|
||||
<MicrosoftExtensionsLoggingTraceSourcePackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsLoggingTraceSourcePackageVersion>
|
||||
<MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>
|
||||
<MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>
|
||||
<MicrosoftExtensionsOptionsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsOptionsPackageVersion>
|
||||
<MicrosoftExtensionsPrimitivesPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsPrimitivesPackageVersion>
|
||||
<MicrosoftExtensionsInternalTransportPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsInternalTransportPackageVersion>
|
||||
<SystemComponentModelAnnotationsPackageVersion>5.0.0-preview.8.20352.6</SystemComponentModelAnnotationsPackageVersion>
|
||||
<SystemDiagnosticsDiagnosticSourcePackageVersion>5.0.0-preview.8.20352.6</SystemDiagnosticsDiagnosticSourcePackageVersion>
|
||||
<SystemDiagnosticsEventLogPackageVersion>5.0.0-preview.8.20352.6</SystemDiagnosticsEventLogPackageVersion>
|
||||
<SystemDrawingCommonPackageVersion>5.0.0-preview.8.20352.6</SystemDrawingCommonPackageVersion>
|
||||
<SystemIOPipelinesPackageVersion>5.0.0-preview.8.20352.6</SystemIOPipelinesPackageVersion>
|
||||
<SystemNetHttpJsonPackageVersion>5.0.0-preview.8.20352.6</SystemNetHttpJsonPackageVersion>
|
||||
<SystemNetHttpWinHttpHandlerPackageVersion>5.0.0-preview.8.20352.6</SystemNetHttpWinHttpHandlerPackageVersion>
|
||||
<SystemNetWebSocketsWebSocketProtocolPackageVersion>5.0.0-preview.8.20352.6</SystemNetWebSocketsWebSocketProtocolPackageVersion>
|
||||
<SystemReflectionMetadataPackageVersion>5.0.0-preview.8.20352.6</SystemReflectionMetadataPackageVersion>
|
||||
<SystemRuntimeCompilerServicesUnsafePackageVersion>5.0.0-preview.8.20352.6</SystemRuntimeCompilerServicesUnsafePackageVersion>
|
||||
<SystemSecurityCryptographyCngPackageVersion>5.0.0-preview.8.20352.6</SystemSecurityCryptographyCngPackageVersion>
|
||||
<SystemSecurityCryptographyPkcsPackageVersion>5.0.0-preview.8.20352.6</SystemSecurityCryptographyPkcsPackageVersion>
|
||||
<SystemSecurityCryptographyXmlPackageVersion>5.0.0-preview.8.20352.6</SystemSecurityCryptographyXmlPackageVersion>
|
||||
<SystemSecurityPermissionsPackageVersion>5.0.0-preview.8.20352.6</SystemSecurityPermissionsPackageVersion>
|
||||
<SystemSecurityPrincipalWindowsPackageVersion>5.0.0-preview.8.20352.6</SystemSecurityPrincipalWindowsPackageVersion>
|
||||
<SystemServiceProcessServiceControllerPackageVersion>5.0.0-preview.8.20352.6</SystemServiceProcessServiceControllerPackageVersion>
|
||||
<SystemTextEncodingsWebPackageVersion>5.0.0-preview.8.20352.6</SystemTextEncodingsWebPackageVersion>
|
||||
<SystemTextJsonPackageVersion>5.0.0-preview.8.20352.6</SystemTextJsonPackageVersion>
|
||||
<SystemThreadingChannelsPackageVersion>5.0.0-preview.8.20352.6</SystemThreadingChannelsPackageVersion>
|
||||
<SystemWindowsExtensionsPackageVersion>5.0.0-preview.8.20352.6</SystemWindowsExtensionsPackageVersion>
|
||||
<!-- Only listed explicitly to workaround https://github.com/dotnet/cli/issues/10528 -->
|
||||
<MicrosoftNETCorePlatformsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftNETCorePlatformsPackageVersion>
|
||||
<MicrosoftNETCorePlatformsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftNETCorePlatformsPackageVersion>
|
||||
<!-- Packages from dotnet/blazor -->
|
||||
<MicrosoftAspNetCoreComponentsWebAssemblyRuntimePackageVersion>3.2.0</MicrosoftAspNetCoreComponentsWebAssemblyRuntimePackageVersion>
|
||||
<!-- Packages from dotnet/efcore -->
|
||||
<dotnetefPackageVersion>5.0.0-preview.7.20326.1</dotnetefPackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreInMemoryPackageVersion>5.0.0-preview.7.20326.1</MicrosoftEntityFrameworkCoreInMemoryPackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreRelationalPackageVersion>5.0.0-preview.7.20326.1</MicrosoftEntityFrameworkCoreRelationalPackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreSqlitePackageVersion>5.0.0-preview.7.20326.1</MicrosoftEntityFrameworkCoreSqlitePackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreSqlServerPackageVersion>5.0.0-preview.7.20326.1</MicrosoftEntityFrameworkCoreSqlServerPackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreToolsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftEntityFrameworkCoreToolsPackageVersion>
|
||||
<MicrosoftEntityFrameworkCorePackageVersion>5.0.0-preview.7.20326.1</MicrosoftEntityFrameworkCorePackageVersion>
|
||||
<dotnetefPackageVersion>5.0.0-preview.8.20353.5</dotnetefPackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreInMemoryPackageVersion>5.0.0-preview.8.20353.5</MicrosoftEntityFrameworkCoreInMemoryPackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreRelationalPackageVersion>5.0.0-preview.8.20353.5</MicrosoftEntityFrameworkCoreRelationalPackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreSqlitePackageVersion>5.0.0-preview.8.20353.5</MicrosoftEntityFrameworkCoreSqlitePackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreSqlServerPackageVersion>5.0.0-preview.8.20353.5</MicrosoftEntityFrameworkCoreSqlServerPackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreToolsPackageVersion>5.0.0-preview.8.20353.5</MicrosoftEntityFrameworkCoreToolsPackageVersion>
|
||||
<MicrosoftEntityFrameworkCorePackageVersion>5.0.0-preview.8.20353.5</MicrosoftEntityFrameworkCorePackageVersion>
|
||||
</PropertyGroup>
|
||||
<!--
|
||||
|
||||
|
|
@ -189,16 +189,16 @@
|
|||
<MicrosoftCodeAnalysisCSharpPackageVersion>3.4.0</MicrosoftCodeAnalysisCSharpPackageVersion>
|
||||
<MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>3.4.0</MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>
|
||||
<MicrosoftIdentityModelClientsActiveDirectoryPackageVersion>3.19.8</MicrosoftIdentityModelClientsActiveDirectoryPackageVersion>
|
||||
<MicrosoftIdentityModelLoggingPackageVersion>6.6.0</MicrosoftIdentityModelLoggingPackageVersion>
|
||||
<MicrosoftIdentityModelProtocolsOpenIdConnectPackageVersion>6.6.0</MicrosoftIdentityModelProtocolsOpenIdConnectPackageVersion>
|
||||
<MicrosoftIdentityModelProtocolsWsFederationPackageVersion>6.6.0</MicrosoftIdentityModelProtocolsWsFederationPackageVersion>
|
||||
<MicrosoftIdentityModelLoggingPackageVersion>5.5.0</MicrosoftIdentityModelLoggingPackageVersion>
|
||||
<MicrosoftIdentityModelProtocolsOpenIdConnectPackageVersion>5.5.0</MicrosoftIdentityModelProtocolsOpenIdConnectPackageVersion>
|
||||
<MicrosoftIdentityModelProtocolsWsFederationPackageVersion>5.5.0</MicrosoftIdentityModelProtocolsWsFederationPackageVersion>
|
||||
<MicrosoftInternalAspNetCoreH2SpecAllPackageVersion>2.2.1</MicrosoftInternalAspNetCoreH2SpecAllPackageVersion>
|
||||
<MicrosoftNETCoreWindowsApiSetsPackageVersion>1.0.1</MicrosoftNETCoreWindowsApiSetsPackageVersion>
|
||||
<MicrosoftOwinSecurityCookiesPackageVersion>3.0.1</MicrosoftOwinSecurityCookiesPackageVersion>
|
||||
<MicrosoftOwinTestingPackageVersion>3.0.1</MicrosoftOwinTestingPackageVersion>
|
||||
<MicrosoftWebAdministrationPackageVersion>11.1.0</MicrosoftWebAdministrationPackageVersion>
|
||||
<MicrosoftWebXdtPackageVersion>1.4.0</MicrosoftWebXdtPackageVersion>
|
||||
<SystemIdentityModelTokensJwtPackageVersion>6.6.0</SystemIdentityModelTokensJwtPackageVersion>
|
||||
<SystemIdentityModelTokensJwtPackageVersion>5.5.0</SystemIdentityModelTokensJwtPackageVersion>
|
||||
<!-- Packages from 2.1/2.2 branches used for site extension build -->
|
||||
<MicrosoftAspNetCoreAzureAppServicesSiteExtension21PackageVersion>2.1.1</MicrosoftAspNetCoreAzureAppServicesSiteExtension21PackageVersion>
|
||||
<MicrosoftAspNetCoreAzureAppServicesSiteExtension22PackageVersion>2.2.0</MicrosoftAspNetCoreAzureAppServicesSiteExtension22PackageVersion>
|
||||
|
|
@ -221,7 +221,7 @@
|
|||
<IdentityServer4EntityFrameworkStoragePackageVersion>3.0.0</IdentityServer4EntityFrameworkStoragePackageVersion>
|
||||
<MessagePackPackageVersion>2.1.90</MessagePackPackageVersion>
|
||||
<MoqPackageVersion>4.10.0</MoqPackageVersion>
|
||||
<MonoCecilPackageVersion>0.10.1</MonoCecilPackageVersion>
|
||||
<MonoCecilPackageVersion>0.11.2</MonoCecilPackageVersion>
|
||||
<NewtonsoftJsonBsonPackageVersion>1.0.2</NewtonsoftJsonBsonPackageVersion>
|
||||
<NewtonsoftJsonPackageVersion>12.0.2</NewtonsoftJsonPackageVersion>
|
||||
<!-- Begin: STOP!!! Razor need to reference the version of JSON that our HOSTS support. -->
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
FROM microsoft/dotnet:2.1.0-preview1-runtime-deps-alpine
|
||||
ARG USER
|
||||
ARG USER_ID
|
||||
ARG GROUP_ID
|
||||
ARG WORKDIR
|
||||
|
||||
WORKDIR ${WORKDIR}
|
||||
RUN mkdir -p "/home/$USER" && chown "${USER_ID}:${GROUP_ID}" "/home/$USER"
|
||||
ENV HOME "/home/$USER"
|
||||
|
||||
RUN apk add --no-cache \
|
||||
bash \
|
||||
wget \
|
||||
git \
|
||||
jq \
|
||||
curl \
|
||||
icu-libs \
|
||||
openssl
|
||||
|
||||
USER $USER_ID:$GROUP_ID
|
||||
|
||||
# Disable the invariant mode (set in base image)
|
||||
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT false
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
ENV LANG en_US.UTF-8
|
||||
|
||||
# Skip package initilization
|
||||
ENV DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
FROM mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-16.04-cross-arm64-alpine10fcdcf-20190208200917
|
||||
ARG USER
|
||||
ARG USER_ID
|
||||
ARG GROUP_ID
|
||||
ARG WORKDIR
|
||||
|
||||
WORKDIR ${WORKDIR}
|
||||
RUN mkdir -p "/home/$USER" && chown "${USER_ID}:${GROUP_ID}" "/home/$USER"
|
||||
ENV HOME "/home/$USER"
|
||||
|
||||
USER $USER_ID:$GROUP_ID
|
||||
|
||||
# Disable the invariant mode (set in base image)
|
||||
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT false
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
ENV LANG en_US.UTF-8
|
||||
|
||||
# Skip package initilization
|
||||
ENV DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<!-- arm64 queues for helix-matrix.yml pipeline -->
|
||||
<ItemGroup Condition="'$(IsWindowsOnlyTest)' != 'true' AND '$(TargetArchitecture)' == 'arm64' AND '$(IsHelixDaily)' == 'true' AND '$(RunQuarantinedTests)' != 'true'">
|
||||
<ItemGroup Condition="'$(IsWindowsOnlyTest)' != 'true' AND '$(TargetArchitecture)' == 'arm64' AND '$(IsHelixDaily)' == 'true'">
|
||||
<HelixAvailableTargetQueue Include="Windows.10.Arm64.Open" Platform="Windows" />
|
||||
<HelixAvailableTargetQueue Include="(Debian.9.Arm64.Open)Ubuntu.1804.Armarch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-9-helix-arm64v8-a12566d-20190807161036" Platform="Linux" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -257,8 +257,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Compon
|
|||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Authentication", "Authentication", "{81250121-9B43-40B1-BF11-CE4458F2676C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Components.WebAssembly.HttpHandler", "WebAssembly\WebAssemblyHttpHandler\src\Microsoft.AspNetCore.Components.WebAssembly.HttpHandler.csproj", "{031AD67E-DDDE-4A20-874A-8D0A791C6F4C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wasm.Authentication.Client", "WebAssembly\testassets\Wasm.Authentication.Client\Wasm.Authentication.Client.csproj", "{5F12F7B9-70BE-48F6-922A-3A1E87EE6BF0}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wasm.Authentication.Shared", "WebAssembly\testassets\Wasm.Authentication.Shared\Wasm.Authentication.Shared.csproj", "{630D5388-7A2F-42DD-9154-1F62A18CBB69}"
|
||||
|
|
@ -1523,18 +1521,6 @@ Global
|
|||
{6B0D6C08-FC30-4822-9464-4D24FF4CDC17}.Release|x64.Build.0 = Release|Any CPU
|
||||
{6B0D6C08-FC30-4822-9464-4D24FF4CDC17}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{6B0D6C08-FC30-4822-9464-4D24FF4CDC17}.Release|x86.Build.0 = Release|Any CPU
|
||||
{031AD67E-DDDE-4A20-874A-8D0A791C6F4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{031AD67E-DDDE-4A20-874A-8D0A791C6F4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{031AD67E-DDDE-4A20-874A-8D0A791C6F4C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{031AD67E-DDDE-4A20-874A-8D0A791C6F4C}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{031AD67E-DDDE-4A20-874A-8D0A791C6F4C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{031AD67E-DDDE-4A20-874A-8D0A791C6F4C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{031AD67E-DDDE-4A20-874A-8D0A791C6F4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{031AD67E-DDDE-4A20-874A-8D0A791C6F4C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{031AD67E-DDDE-4A20-874A-8D0A791C6F4C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{031AD67E-DDDE-4A20-874A-8D0A791C6F4C}.Release|x64.Build.0 = Release|Any CPU
|
||||
{031AD67E-DDDE-4A20-874A-8D0A791C6F4C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{031AD67E-DDDE-4A20-874A-8D0A791C6F4C}.Release|x86.Build.0 = Release|Any CPU
|
||||
{5F12F7B9-70BE-48F6-922A-3A1E87EE6BF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5F12F7B9-70BE-48F6-922A-3A1E87EE6BF0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5F12F7B9-70BE-48F6-922A-3A1E87EE6BF0}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
|
|
@ -1687,7 +1673,6 @@ Global
|
|||
{5CD61479-5181-4A5B-B90F-9F34316248B3} = {81250121-9B43-40B1-BF11-CE4458F2676C}
|
||||
{6B0D6C08-FC30-4822-9464-4D24FF4CDC17} = {81250121-9B43-40B1-BF11-CE4458F2676C}
|
||||
{81250121-9B43-40B1-BF11-CE4458F2676C} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF}
|
||||
{031AD67E-DDDE-4A20-874A-8D0A791C6F4C} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF}
|
||||
{5F12F7B9-70BE-48F6-922A-3A1E87EE6BF0} = {A7ABAC29-F73F-456D-AE54-46842CFC2E10}
|
||||
{630D5388-7A2F-42DD-9154-1F62A18CBB69} = {A7ABAC29-F73F-456D-AE54-46842CFC2E10}
|
||||
{A062ACCE-AB0D-4569-9548-4BC0D9A9174B} = {2FC10057-7A0A-4E34-8302-879925BC0102}
|
||||
|
|
|
|||
|
|
@ -125,8 +125,14 @@ namespace Microsoft.AspNetCore.Components
|
|||
private readonly object _dummy;
|
||||
private readonly int _dummyPrimitive;
|
||||
public ElementReference(string id) { throw null; }
|
||||
public ElementReference(string id, Microsoft.AspNetCore.Components.ElementReferenceContext? context) { throw null; }
|
||||
public Microsoft.AspNetCore.Components.ElementReferenceContext? Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
public string Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
}
|
||||
public abstract partial class ElementReferenceContext
|
||||
{
|
||||
protected ElementReferenceContext() { }
|
||||
}
|
||||
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
|
||||
public readonly partial struct EventCallback
|
||||
{
|
||||
|
|
@ -468,6 +474,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
{
|
||||
public Renderer(System.IServiceProvider serviceProvider, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { }
|
||||
public abstract Microsoft.AspNetCore.Components.Dispatcher Dispatcher { get; }
|
||||
protected internal Microsoft.AspNetCore.Components.ElementReferenceContext? ElementReferenceContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } }
|
||||
public event System.UnhandledExceptionEventHandler UnhandledSynchronizationException { add { } remove { } }
|
||||
protected internal int AssignRootComponentId(Microsoft.AspNetCore.Components.IComponent component) { throw null; }
|
||||
public virtual System.Threading.Tasks.Task DispatchEventAsync(ulong eventHandlerId, Microsoft.AspNetCore.Components.RenderTree.EventFieldInfo fieldInfo, System.EventArgs eventArgs) { throw null; }
|
||||
|
|
|
|||
|
|
@ -125,8 +125,14 @@ namespace Microsoft.AspNetCore.Components
|
|||
private readonly object _dummy;
|
||||
private readonly int _dummyPrimitive;
|
||||
public ElementReference(string id) { throw null; }
|
||||
public ElementReference(string id, Microsoft.AspNetCore.Components.ElementReferenceContext? context) { throw null; }
|
||||
public Microsoft.AspNetCore.Components.ElementReferenceContext? Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
public string Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
}
|
||||
public abstract partial class ElementReferenceContext
|
||||
{
|
||||
protected ElementReferenceContext() { }
|
||||
}
|
||||
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
|
||||
public readonly partial struct EventCallback
|
||||
{
|
||||
|
|
@ -467,6 +473,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
{
|
||||
public Renderer(System.IServiceProvider serviceProvider, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { }
|
||||
public abstract Microsoft.AspNetCore.Components.Dispatcher Dispatcher { get; }
|
||||
protected internal Microsoft.AspNetCore.Components.ElementReferenceContext? ElementReferenceContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } }
|
||||
public event System.UnhandledExceptionEventHandler UnhandledSynchronizationException { add { } remove { } }
|
||||
protected internal int AssignRootComponentId(Microsoft.AspNetCore.Components.IComponent component) { throw null; }
|
||||
public virtual System.Threading.Tasks.Task DispatchEventAsync(ulong eventHandlerId, Microsoft.AspNetCore.Components.RenderTree.EventFieldInfo fieldInfo, System.EventArgs eventArgs) { throw null; }
|
||||
|
|
|
|||
|
|
@ -23,13 +23,32 @@ namespace Microsoft.AspNetCore.Components
|
|||
/// </remarks>
|
||||
public string Id { get; }
|
||||
|
||||
public ElementReference(string id)
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ElementReferenceContext"/> instance.
|
||||
/// </summary>
|
||||
public ElementReferenceContext? Context { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates a new <see cref="ElementReference" />.
|
||||
/// </summary>
|
||||
/// <param name="id">A unique identifier for this <see cref="ElementReference"/>.</param>
|
||||
/// <param name="context">The nullable <see cref="ElementReferenceContext"/> instance.</param>
|
||||
public ElementReference(string id, ElementReferenceContext? context)
|
||||
{
|
||||
Id = id;
|
||||
Context = context;
|
||||
}
|
||||
|
||||
internal static ElementReference CreateWithUniqueId()
|
||||
=> new ElementReference(CreateUniqueId());
|
||||
/// <summary>
|
||||
/// Instantiates a new <see cref="ElementReference"/>.
|
||||
/// </summary>
|
||||
/// <param name="id">A unique identifier for this <see cref="ElementReference"/>.</param>
|
||||
public ElementReference(string id) : this(id, null)
|
||||
{
|
||||
}
|
||||
|
||||
internal static ElementReference CreateWithUniqueId(ElementReferenceContext? context)
|
||||
=> new ElementReference(CreateUniqueId(), context);
|
||||
|
||||
private static string CreateUniqueId()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNetCore.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Context for an <see cref="ElementReference"/>.
|
||||
/// </summary>
|
||||
public abstract class ElementReferenceContext
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<Compile Include="$(ComponentsSharedSourceRoot)src\ArrayBuilder.cs" LinkBase="RenderTree" />
|
||||
<Compile Include="$(ComponentsSharedSourceRoot)src\WebAssemblyJSInteropInternalCalls.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Components
|
|||
|
||||
static PlatformInfo()
|
||||
{
|
||||
IsWebAssembly = RuntimeInformation.IsOSPlatform(OSPlatform.Create("WEBASSEMBLY"));
|
||||
IsWebAssembly = RuntimeInformation.IsOSPlatform(OSPlatform.Browser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.Profiling
|
||||
{
|
||||
internal abstract class ComponentsProfiling
|
||||
{
|
||||
// For now, this is only intended for use on Blazor WebAssembly, and will have no effect
|
||||
// when running on Blazor Server. The reason for having the ComponentsProfiling abstraction
|
||||
// is so that if we later have two different implementations (one for WebAssembly, one for
|
||||
// Server), the execution characteristics of calling Start/End will be unchanged and historical
|
||||
// perf data will still be comparable to newer data.
|
||||
public static readonly ComponentsProfiling Instance = PlatformInfo.IsWebAssembly
|
||||
? new WebAssemblyComponentsProfiling()
|
||||
: (ComponentsProfiling)new NoOpComponentsProfiling();
|
||||
|
||||
public abstract void Start([CallerMemberName] string? name = null);
|
||||
public abstract void End([CallerMemberName] string? name = null);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.Profiling
|
||||
{
|
||||
internal class NoOpComponentsProfiling : ComponentsProfiling
|
||||
{
|
||||
public override void Start(string? name)
|
||||
{
|
||||
}
|
||||
|
||||
public override void End(string? name)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using WebAssembly.JSInterop;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.Profiling
|
||||
{
|
||||
// Later on, we will likely want to move this into the WebAssembly package. However it needs to
|
||||
// be inlined into the Components package directly until we're ready to make the underlying
|
||||
// ComponentsProfile abstraction into a public API. It's possible that this API will never become
|
||||
// public, or that it will be replaced by something more standard for .NET, if it's possible to
|
||||
// make that work performantly on WebAssembly.
|
||||
|
||||
internal class WebAssemblyComponentsProfiling : ComponentsProfiling
|
||||
{
|
||||
static bool IsCapturing = false;
|
||||
|
||||
public static void SetCapturing(bool isCapturing)
|
||||
{
|
||||
IsCapturing = isCapturing;
|
||||
}
|
||||
|
||||
public override void Start(string? name)
|
||||
{
|
||||
if (IsCapturing)
|
||||
{
|
||||
InternalCalls.InvokeJSUnmarshalled<string, object, object, object>(
|
||||
out _, "_blazorProfileStart", name, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
public override void End(string? name)
|
||||
{
|
||||
if (IsCapturing)
|
||||
{
|
||||
InternalCalls.InvokeJSUnmarshalled<string, object, object, object>(
|
||||
out _, "_blazorProfileEnd", name, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,9 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.AspNetCore.Components.Profiling;
|
||||
using Microsoft.AspNetCore.Components.Rendering;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.RenderTree
|
||||
|
|
@ -25,6 +28,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
ArrayRange<RenderTreeFrame> oldTree,
|
||||
ArrayRange<RenderTreeFrame> newTree)
|
||||
{
|
||||
ComponentsProfiling.Instance.Start();
|
||||
var editsBuffer = batchBuilder.EditsBuffer;
|
||||
var editsBufferStartLength = editsBuffer.Count;
|
||||
|
||||
|
|
@ -32,7 +36,9 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
AppendDiffEntriesForRange(ref diffContext, 0, oldTree.Count, 0, newTree.Count);
|
||||
|
||||
var editsSegment = editsBuffer.ToSegment(editsBufferStartLength, editsBuffer.Count);
|
||||
return new RenderTreeDiff(componentId, editsSegment);
|
||||
var result = new RenderTreeDiff(componentId, editsSegment);
|
||||
ComponentsProfiling.Instance.End();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void DisposeFrames(RenderBatchBuilder batchBuilder, ArrayRange<RenderTreeFrame> frames)
|
||||
|
|
@ -43,6 +49,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
int oldStartIndex, int oldEndIndexExcl,
|
||||
int newStartIndex, int newEndIndexExcl)
|
||||
{
|
||||
ProfilingStart();
|
||||
// This is deliberately a very large method. Parts of it could be factored out
|
||||
// into other private methods, but doing so comes at a consequential perf cost,
|
||||
// because it involves so much parameter passing. You can think of the code here
|
||||
|
|
@ -293,10 +300,12 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
diffContext.KeyedItemInfoDictionaryPool.Return(keyedItemInfos);
|
||||
}
|
||||
}
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
private static Dictionary<object, KeyedItemInfo> BuildKeyToInfoLookup(DiffContext diffContext, int oldStartIndex, int oldEndIndexExcl, int newStartIndex, int newEndIndexExcl)
|
||||
{
|
||||
ProfilingStart();
|
||||
var result = diffContext.KeyedItemInfoDictionaryPool.Get();
|
||||
var oldTree = diffContext.OldTree;
|
||||
var newTree = diffContext.NewTree;
|
||||
|
|
@ -342,6 +351,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
newStartIndex = NextSiblingIndex(frame, newStartIndex);
|
||||
}
|
||||
|
||||
ProfilingEnd();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -374,6 +384,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
int oldStartIndex, int oldEndIndexExcl,
|
||||
int newStartIndex, int newEndIndexExcl)
|
||||
{
|
||||
ProfilingStart();
|
||||
// The overhead of the dictionary used by AppendAttributeDiffEntriesForRangeSlow is
|
||||
// significant, so we want to try and do a merge-join if possible, but fall back to
|
||||
// a hash-join if not. We'll do a merge join until we hit a case we can't handle and
|
||||
|
|
@ -422,6 +433,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
ref diffContext,
|
||||
oldStartIndex, oldEndIndexExcl,
|
||||
newStartIndex, newEndIndexExcl);
|
||||
ProfilingEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -447,9 +459,12 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
ref diffContext,
|
||||
oldStartIndex, oldEndIndexExcl,
|
||||
newStartIndex, newEndIndexExcl);
|
||||
ProfilingEnd();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
private static void AppendAttributeDiffEntriesForRangeSlow(
|
||||
|
|
@ -457,6 +472,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
int oldStartIndex, int oldEndIndexExcl,
|
||||
int newStartIndex, int newEndIndexExcl)
|
||||
{
|
||||
ProfilingStart();
|
||||
var oldTree = diffContext.OldTree;
|
||||
var newTree = diffContext.NewTree;
|
||||
|
||||
|
|
@ -495,6 +511,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
|
||||
// We should have processed any additions at this point. Reset for the next batch.
|
||||
diffContext.AttributeDiffSet.Clear();
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
private static void UpdateRetainedChildComponent(
|
||||
|
|
@ -502,6 +519,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
int oldComponentIndex,
|
||||
int newComponentIndex)
|
||||
{
|
||||
ProfilingStart();
|
||||
var oldTree = diffContext.OldTree;
|
||||
var newTree = diffContext.NewTree;
|
||||
ref var oldComponentFrame = ref oldTree[oldComponentIndex];
|
||||
|
|
@ -528,6 +546,8 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
{
|
||||
componentState.SetDirectParameters(newParameters);
|
||||
}
|
||||
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
private static int NextSiblingIndex(in RenderTreeFrame frame, int frameIndex)
|
||||
|
|
@ -550,6 +570,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
int oldFrameIndex,
|
||||
int newFrameIndex)
|
||||
{
|
||||
ProfilingStart();
|
||||
var oldTree = diffContext.OldTree;
|
||||
var newTree = diffContext.NewTree;
|
||||
ref var oldFrame = ref oldTree[oldFrameIndex];
|
||||
|
|
@ -562,6 +583,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
{
|
||||
InsertNewFrame(ref diffContext, newFrameIndex);
|
||||
RemoveOldFrame(ref diffContext, oldFrameIndex);
|
||||
ProfilingEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -687,6 +709,8 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
default:
|
||||
throw new NotImplementedException($"Encountered unsupported frame type during diffing: {newTree[newFrameIndex].FrameType}");
|
||||
}
|
||||
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
// This should only be called for attributes that have the same name. This is an
|
||||
|
|
@ -696,6 +720,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
int oldFrameIndex,
|
||||
int newFrameIndex)
|
||||
{
|
||||
ProfilingStart();
|
||||
var oldTree = diffContext.OldTree;
|
||||
var newTree = diffContext.NewTree;
|
||||
ref var oldFrame = ref oldTree[oldFrameIndex];
|
||||
|
|
@ -724,10 +749,13 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
// since it was unchanged.
|
||||
newFrame = oldFrame;
|
||||
}
|
||||
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
private static void InsertNewFrame(ref DiffContext diffContext, int newFrameIndex)
|
||||
{
|
||||
ProfilingStart();
|
||||
var newTree = diffContext.NewTree;
|
||||
ref var newFrame = ref newTree[newFrameIndex];
|
||||
switch (newFrame.FrameType)
|
||||
|
|
@ -780,10 +808,12 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
default:
|
||||
throw new NotImplementedException($"Unexpected frame type during {nameof(InsertNewFrame)}: {newFrame.FrameType}");
|
||||
}
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
private static void RemoveOldFrame(ref DiffContext diffContext, int oldFrameIndex)
|
||||
{
|
||||
ProfilingStart();
|
||||
var oldTree = diffContext.OldTree;
|
||||
ref var oldFrame = ref oldTree[oldFrameIndex];
|
||||
switch (oldFrame.FrameType)
|
||||
|
|
@ -825,6 +855,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
default:
|
||||
throw new NotImplementedException($"Unexpected frame type during {nameof(RemoveOldFrame)}: {oldFrame.FrameType}");
|
||||
}
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
private static int GetAttributesEndIndexExclusive(RenderTreeFrame[] tree, int rootIndex)
|
||||
|
|
@ -858,6 +889,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
|
||||
private static void InitializeNewSubtree(ref DiffContext diffContext, int frameIndex)
|
||||
{
|
||||
ProfilingStart();
|
||||
var frames = diffContext.NewTree;
|
||||
var endIndexExcl = frameIndex + frames[frameIndex].ElementSubtreeLength;
|
||||
for (var i = frameIndex; i < endIndexExcl; i++)
|
||||
|
|
@ -879,10 +911,12 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
break;
|
||||
}
|
||||
}
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
private static void InitializeNewComponentFrame(ref DiffContext diffContext, int frameIndex)
|
||||
{
|
||||
ProfilingStart();
|
||||
var frames = diffContext.NewTree;
|
||||
ref var frame = ref frames[frameIndex];
|
||||
|
||||
|
|
@ -899,6 +933,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
var initialParametersLifetime = new ParameterViewLifetime(diffContext.BatchBuilder);
|
||||
var initialParameters = new ParameterView(initialParametersLifetime, frames, frameIndex);
|
||||
childComponentState.SetDirectParameters(initialParameters);
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
private static void InitializeNewAttributeFrame(ref DiffContext diffContext, ref RenderTreeFrame newFrame)
|
||||
|
|
@ -917,7 +952,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
|
||||
private static void InitializeNewElementReferenceCaptureFrame(ref DiffContext diffContext, ref RenderTreeFrame newFrame)
|
||||
{
|
||||
var newElementReference = ElementReference.CreateWithUniqueId();
|
||||
var newElementReference = ElementReference.CreateWithUniqueId(diffContext.Renderer.ElementReferenceContext);
|
||||
newFrame = newFrame.WithElementReferenceCaptureId(newElementReference.Id);
|
||||
newFrame.ElementReferenceCaptureAction(newElementReference);
|
||||
}
|
||||
|
|
@ -943,6 +978,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
|
||||
private static void DisposeFramesInRange(RenderBatchBuilder batchBuilder, RenderTreeFrame[] frames, int startIndex, int endIndexExcl)
|
||||
{
|
||||
ProfilingStart();
|
||||
for (var i = startIndex; i < endIndexExcl; i++)
|
||||
{
|
||||
ref var frame = ref frames[i];
|
||||
|
|
@ -955,6 +991,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
batchBuilder.DisposedEventHandlerIds.Append(frame.AttributeEventHandlerId);
|
||||
}
|
||||
}
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -996,5 +1033,18 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
SiblingIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Having too many calls to ComponentsProfiling.Instance.Start/End has a measurable perf impact
|
||||
// even when capturing is disabled. So, to enable detailed profiling for this class, define the
|
||||
// Profile_RenderTreeDiffBuilder compiler symbol, otherwise the calls are compiled out entirely.
|
||||
// Enabling detailed profiling adds about 5% to rendering benchmark times.
|
||||
|
||||
[Conditional("Profile_RenderTreeDiffBuilder")]
|
||||
private static void ProfilingStart([CallerMemberName] string? name = null)
|
||||
=> ComponentsProfiling.Instance.Start(name);
|
||||
|
||||
[Conditional("Profile_RenderTreeDiffBuilder")]
|
||||
private static void ProfilingEnd([CallerMemberName] string? name = null)
|
||||
=> ComponentsProfiling.Instance.End(name);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using System.Collections.Generic;
|
|||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components.Profiling;
|
||||
using Microsoft.AspNetCore.Components.Rendering;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
|
|
@ -76,6 +77,12 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
/// </summary>
|
||||
public abstract Dispatcher Dispatcher { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="Components.ElementReferenceContext"/> associated with this <see cref="Renderer"/>,
|
||||
/// if it exists.
|
||||
/// </summary>
|
||||
protected internal ElementReferenceContext? ElementReferenceContext { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new component of the specified type.
|
||||
/// </summary>
|
||||
|
|
@ -214,6 +221,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
/// </returns>
|
||||
public virtual Task DispatchEventAsync(ulong eventHandlerId, EventFieldInfo fieldInfo, EventArgs eventArgs)
|
||||
{
|
||||
ComponentsProfiling.Instance.Start();
|
||||
Dispatcher.AssertAccess();
|
||||
|
||||
if (!_eventBindings.TryGetValue(eventHandlerId, out var callback))
|
||||
|
|
@ -241,6 +249,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
catch (Exception e)
|
||||
{
|
||||
HandleException(e);
|
||||
ComponentsProfiling.Instance.End();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
finally
|
||||
|
|
@ -254,7 +263,9 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
|
||||
// Task completed synchronously or is still running. We already processed all of the rendering
|
||||
// work that was queued so let our error handler deal with it.
|
||||
return GetErrorHandledTask(task);
|
||||
var result = GetErrorHandledTask(task);
|
||||
ComponentsProfiling.Instance.End();
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void InstantiateChildComponentOnFrame(ref RenderTreeFrame frame, int parentComponentId)
|
||||
|
|
@ -404,6 +415,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
|
||||
private void ProcessRenderQueue()
|
||||
{
|
||||
ComponentsProfiling.Instance.Start();
|
||||
Dispatcher.AssertAccess();
|
||||
|
||||
if (_isBatchInProgress)
|
||||
|
|
@ -418,6 +430,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
{
|
||||
if (_batchBuilder.ComponentRenderQueue.Count == 0)
|
||||
{
|
||||
ComponentsProfiling.Instance.End();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -429,7 +442,9 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
}
|
||||
|
||||
var batch = _batchBuilder.ToBatch();
|
||||
ComponentsProfiling.Instance.Start(nameof(UpdateDisplayAsync));
|
||||
updateDisplayTask = UpdateDisplayAsync(batch);
|
||||
ComponentsProfiling.Instance.End(nameof(UpdateDisplayAsync));
|
||||
|
||||
// Fire off the execution of OnAfterRenderAsync, but don't wait for it
|
||||
// if there is async work to be done.
|
||||
|
|
@ -439,6 +454,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
{
|
||||
// Ensure we catch errors while running the render functions of the components.
|
||||
HandleException(e);
|
||||
ComponentsProfiling.Instance.End();
|
||||
return;
|
||||
}
|
||||
finally
|
||||
|
|
@ -456,6 +472,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
{
|
||||
ProcessRenderQueue();
|
||||
}
|
||||
ComponentsProfiling.Instance.End();
|
||||
}
|
||||
|
||||
private Task InvokeRenderCompletedCalls(ArrayRange<RenderTreeDiff> updatedComponents, Task updateDisplayTask)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components.Profiling;
|
||||
using Microsoft.AspNetCore.Components.RenderTree;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.Rendering
|
||||
|
|
@ -56,6 +57,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
|
||||
public void RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment)
|
||||
{
|
||||
ComponentsProfiling.Instance.Start();
|
||||
// A component might be in the render queue already before getting disposed by an
|
||||
// earlier entry in the render queue. In that case, rendering is a no-op.
|
||||
if (_componentWasDisposed)
|
||||
|
|
@ -67,7 +69,9 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
(CurrentRenderTree, _renderTreeBuilderPrevious) = (_renderTreeBuilderPrevious, CurrentRenderTree);
|
||||
|
||||
CurrentRenderTree.Clear();
|
||||
ComponentsProfiling.Instance.Start("BuildRenderTree");
|
||||
renderFragment(CurrentRenderTree);
|
||||
ComponentsProfiling.Instance.End("BuildRenderTree");
|
||||
|
||||
var diff = RenderTreeDiffBuilder.ComputeDiff(
|
||||
_renderer,
|
||||
|
|
@ -77,6 +81,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
CurrentRenderTree.GetFrames());
|
||||
batchBuilder.UpdatedComponentDiffs.Append(diff);
|
||||
batchBuilder.InvalidateParameterViews();
|
||||
ComponentsProfiling.Instance.End();
|
||||
}
|
||||
|
||||
public bool TryDisposeInBatch(RenderBatchBuilder batchBuilder, [NotNullWhen(false)] out Exception? exception)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.AspNetCore.Components.Profiling;
|
||||
using Microsoft.AspNetCore.Components.RenderTree;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.Rendering
|
||||
|
|
@ -43,6 +45,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// <param name="elementName">A value representing the type of the element.</param>
|
||||
public void OpenElement(int sequence, string elementName)
|
||||
{
|
||||
ProfilingStart();
|
||||
// We are entering a new scope, since we track the "duplicate attributes" per
|
||||
// element/component we might need to clean them up now.
|
||||
if (_hasSeenAddMultipleAttributes)
|
||||
|
|
@ -53,6 +56,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
|
||||
_openElementIndices.Push(_entries.Count);
|
||||
Append(RenderTreeFrame.Element(sequence, elementName));
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -61,6 +65,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// </summary>
|
||||
public void CloseElement()
|
||||
{
|
||||
ProfilingStart();
|
||||
var indexOfEntryBeingClosed = _openElementIndices.Pop();
|
||||
|
||||
// We might be closing an element with only attributes, run the duplicate cleanup pass
|
||||
|
|
@ -72,6 +77,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
|
||||
ref var entry = ref _entries.Buffer[indexOfEntryBeingClosed];
|
||||
entry = entry.WithElementSubtreeLength(_entries.Count - indexOfEntryBeingClosed);
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -80,7 +86,11 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// <param name="sequence">An integer that represents the position of the instruction in the source code.</param>
|
||||
/// <param name="markupContent">Content for the new markup frame.</param>
|
||||
public void AddMarkupContent(int sequence, string? markupContent)
|
||||
=> Append(RenderTreeFrame.Markup(sequence, markupContent ?? string.Empty));
|
||||
{
|
||||
ProfilingStart();
|
||||
Append(RenderTreeFrame.Markup(sequence, markupContent ?? string.Empty));
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Appends a frame representing text content.
|
||||
|
|
@ -88,7 +98,11 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// <param name="sequence">An integer that represents the position of the instruction in the source code.</param>
|
||||
/// <param name="textContent">Content for the new text frame.</param>
|
||||
public void AddContent(int sequence, string? textContent)
|
||||
=> Append(RenderTreeFrame.Text(sequence, textContent ?? string.Empty));
|
||||
{
|
||||
ProfilingStart();
|
||||
Append(RenderTreeFrame.Text(sequence, textContent ?? string.Empty));
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Appends frames representing an arbitrary fragment of content.
|
||||
|
|
@ -97,6 +111,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// <param name="fragment">Content to append.</param>
|
||||
public void AddContent(int sequence, RenderFragment? fragment)
|
||||
{
|
||||
ProfilingStart();
|
||||
if (fragment != null)
|
||||
{
|
||||
// We surround the fragment with a region delimiter to indicate that the
|
||||
|
|
@ -107,6 +122,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
fragment(this);
|
||||
CloseRegion();
|
||||
}
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -117,10 +133,12 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// <param name="value">The value used by <paramref name="fragment"/>.</param>
|
||||
public void AddContent<TValue>(int sequence, RenderFragment<TValue>? fragment, TValue value)
|
||||
{
|
||||
ProfilingStart();
|
||||
if (fragment != null)
|
||||
{
|
||||
AddContent(sequence, fragment(value));
|
||||
}
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -153,6 +171,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// <param name="value">The value of the attribute.</param>
|
||||
public void AddAttribute(int sequence, string name, bool value)
|
||||
{
|
||||
ProfilingStart();
|
||||
AssertCanAddAttribute();
|
||||
if (_lastNonAttributeFrameType == RenderTreeFrameType.Component)
|
||||
{
|
||||
|
|
@ -168,6 +187,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
{
|
||||
TrackAttributeName(name);
|
||||
}
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -184,6 +204,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// <param name="value">The value of the attribute.</param>
|
||||
public void AddAttribute(int sequence, string name, string? value)
|
||||
{
|
||||
ProfilingStart();
|
||||
AssertCanAddAttribute();
|
||||
if (value != null || _lastNonAttributeFrameType == RenderTreeFrameType.Component)
|
||||
{
|
||||
|
|
@ -193,6 +214,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
{
|
||||
TrackAttributeName(name);
|
||||
}
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -209,6 +231,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// <param name="value">The value of the attribute.</param>
|
||||
public void AddAttribute(int sequence, string name, MulticastDelegate? value)
|
||||
{
|
||||
ProfilingStart();
|
||||
AssertCanAddAttribute();
|
||||
if (value != null || _lastNonAttributeFrameType == RenderTreeFrameType.Component)
|
||||
{
|
||||
|
|
@ -218,6 +241,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
{
|
||||
TrackAttributeName(name);
|
||||
}
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -238,6 +262,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// </remarks>
|
||||
public void AddAttribute(int sequence, string name, EventCallback value)
|
||||
{
|
||||
ProfilingStart();
|
||||
AssertCanAddAttribute();
|
||||
if (_lastNonAttributeFrameType == RenderTreeFrameType.Component)
|
||||
{
|
||||
|
|
@ -262,6 +287,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
// Track the attribute name if needed since we elided the frame.
|
||||
TrackAttributeName(name);
|
||||
}
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -282,6 +308,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// </remarks>
|
||||
public void AddAttribute<TArgument>(int sequence, string name, EventCallback<TArgument> value)
|
||||
{
|
||||
ProfilingStart();
|
||||
AssertCanAddAttribute();
|
||||
if (_lastNonAttributeFrameType == RenderTreeFrameType.Component)
|
||||
{
|
||||
|
|
@ -306,6 +333,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
// Track the attribute name if needed since we elided the frame.
|
||||
TrackAttributeName(name);
|
||||
}
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -319,6 +347,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// <param name="value">The value of the attribute.</param>
|
||||
public void AddAttribute(int sequence, string name, object? value)
|
||||
{
|
||||
ProfilingStart();
|
||||
// This looks a bit daunting because we need to handle the boxed/object version of all of the
|
||||
// types that AddAttribute special cases.
|
||||
if (_lastNonAttributeFrameType == RenderTreeFrameType.Element)
|
||||
|
|
@ -371,6 +400,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
// This is going to throw. Calling it just to get a consistent exception message.
|
||||
AssertCanAddAttribute();
|
||||
}
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -385,6 +415,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// <param name="frame">A <see cref="RenderTreeFrame"/> holding the name and value of the attribute.</param>
|
||||
public void AddAttribute(int sequence, in RenderTreeFrame frame)
|
||||
{
|
||||
ProfilingStart();
|
||||
if (frame.FrameType != RenderTreeFrameType.Attribute)
|
||||
{
|
||||
throw new ArgumentException($"The {nameof(frame.FrameType)} must be {RenderTreeFrameType.Attribute}.");
|
||||
|
|
@ -392,6 +423,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
|
||||
AssertCanAddAttribute();
|
||||
Append(frame.WithAttributeSequence(sequence));
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -401,6 +433,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// <param name="attributes">A collection of key-value pairs representing attributes.</param>
|
||||
public void AddMultipleAttributes(int sequence, IEnumerable<KeyValuePair<string, object>>? attributes)
|
||||
{
|
||||
ProfilingStart();
|
||||
// Calling this up-front just to make sure we validate before mutating anything.
|
||||
AssertCanAddAttribute();
|
||||
|
||||
|
|
@ -417,6 +450,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
AddAttribute(sequence, attribute.Key, attribute.Value);
|
||||
}
|
||||
}
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -433,6 +467,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// <param name="updatesAttributeName">The name of another attribute whose value can be updated when the event handler is executed.</param>
|
||||
public void SetUpdatesAttributeName(string updatesAttributeName)
|
||||
{
|
||||
ProfilingStart();
|
||||
if (_entries.Count == 0)
|
||||
{
|
||||
throw new InvalidOperationException("No preceding attribute frame exists.");
|
||||
|
|
@ -445,6 +480,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
}
|
||||
|
||||
prevFrame = prevFrame.WithAttributeEventUpdatesAttributeName(updatesAttributeName);
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -476,10 +512,12 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// <param name="value">The value for the key.</param>
|
||||
public void SetKey(object? value)
|
||||
{
|
||||
ProfilingStart();
|
||||
if (value == null)
|
||||
{
|
||||
// Null is equivalent to not having set a key, which is valuable because Razor syntax doesn't have an
|
||||
// easy way to have conditional directive attributes
|
||||
ProfilingEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -502,10 +540,12 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
default:
|
||||
throw new InvalidOperationException($"Cannot set a key on a frame of type {parentFrame.FrameType}.");
|
||||
}
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
private void OpenComponentUnchecked(int sequence, Type componentType)
|
||||
{
|
||||
ProfilingStart();
|
||||
// We are entering a new scope, since we track the "duplicate attributes" per
|
||||
// element/component we might need to clean them up now.
|
||||
if (_hasSeenAddMultipleAttributes)
|
||||
|
|
@ -516,6 +556,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
|
||||
_openElementIndices.Push(_entries.Count);
|
||||
Append(RenderTreeFrame.ChildComponent(sequence, componentType));
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -524,6 +565,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// </summary>
|
||||
public void CloseComponent()
|
||||
{
|
||||
ProfilingStart();
|
||||
var indexOfEntryBeingClosed = _openElementIndices.Pop();
|
||||
|
||||
// We might be closing a component with only attributes. Run the attribute cleanup pass
|
||||
|
|
@ -535,6 +577,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
|
||||
ref var entry = ref _entries.Buffer[indexOfEntryBeingClosed];
|
||||
entry = entry.WithComponentSubtreeLength(_entries.Count - indexOfEntryBeingClosed);
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -544,12 +587,14 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// <param name="elementReferenceCaptureAction">An action to be invoked whenever the reference value changes.</param>
|
||||
public void AddElementReferenceCapture(int sequence, Action<ElementReference> elementReferenceCaptureAction)
|
||||
{
|
||||
ProfilingStart();
|
||||
if (GetCurrentParentFrameType() != RenderTreeFrameType.Element)
|
||||
{
|
||||
throw new InvalidOperationException($"Element reference captures may only be added as children of frames of type {RenderTreeFrameType.Element}");
|
||||
}
|
||||
|
||||
Append(RenderTreeFrame.ElementReferenceCapture(sequence, elementReferenceCaptureAction));
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -559,6 +604,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// <param name="componentReferenceCaptureAction">An action to be invoked whenever the reference value changes.</param>
|
||||
public void AddComponentReferenceCapture(int sequence, Action<object?> componentReferenceCaptureAction)
|
||||
{
|
||||
ProfilingStart();
|
||||
var parentFrameIndex = GetCurrentParentFrameIndex();
|
||||
if (!parentFrameIndex.HasValue)
|
||||
{
|
||||
|
|
@ -572,6 +618,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
}
|
||||
|
||||
Append(RenderTreeFrame.ComponentReferenceCapture(sequence, componentReferenceCaptureAction, parentFrameIndexValue));
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -580,6 +627,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// <param name="sequence">An integer that represents the position of the instruction in the source code.</param>
|
||||
public void OpenRegion(int sequence)
|
||||
{
|
||||
ProfilingStart();
|
||||
// We are entering a new scope, since we track the "duplicate attributes" per
|
||||
// element/component we might need to clean them up now.
|
||||
if (_hasSeenAddMultipleAttributes)
|
||||
|
|
@ -590,6 +638,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
|
||||
_openElementIndices.Push(_entries.Count);
|
||||
Append(RenderTreeFrame.Region(sequence));
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -598,9 +647,11 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// </summary>
|
||||
public void CloseRegion()
|
||||
{
|
||||
ProfilingStart();
|
||||
var indexOfEntryBeingClosed = _openElementIndices.Pop();
|
||||
ref var entry = ref _entries.Buffer[indexOfEntryBeingClosed];
|
||||
entry = entry.WithRegionSubtreeLength(_entries.Count - indexOfEntryBeingClosed);
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
private void AssertCanAddAttribute()
|
||||
|
|
@ -628,24 +679,29 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
ProfilingStart();
|
||||
_entries.Clear();
|
||||
_openElementIndices.Clear();
|
||||
_lastNonAttributeFrameType = null;
|
||||
_hasSeenAddMultipleAttributes = false;
|
||||
_seenAttributeNames?.Clear();
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
// internal because this should only be used during the post-event tree patching logic
|
||||
// It's expensive because it involves copying all the subsequent memory in the array
|
||||
internal void InsertAttributeExpensive(int insertAtIndex, int sequence, string attributeName, object? attributeValue)
|
||||
{
|
||||
ProfilingStart();
|
||||
// Replicate the same attribute omission logic as used elsewhere
|
||||
if ((attributeValue == null) || (attributeValue is bool boolValue && !boolValue))
|
||||
{
|
||||
ProfilingEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
_entries.InsertExpensive(insertAtIndex, RenderTreeFrame.Attribute(sequence, attributeName, attributeValue));
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -669,6 +725,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
// Internal for testing
|
||||
internal void ProcessDuplicateAttributes(int first)
|
||||
{
|
||||
ProfilingStart();
|
||||
Debug.Assert(_hasSeenAddMultipleAttributes);
|
||||
|
||||
// When AddMultipleAttributes method has been called, we need to postprocess attributes while closing
|
||||
|
|
@ -750,6 +807,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
|
||||
seenAttributeNames.Clear();
|
||||
_hasSeenAddMultipleAttributes = false;
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
// Internal for testing
|
||||
|
|
@ -766,7 +824,22 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
ProfilingStart();
|
||||
_entries.Dispose();
|
||||
ProfilingEnd();
|
||||
}
|
||||
|
||||
// Having too many calls to ComponentsProfiling.Instance.Start/End has a measurable perf impact
|
||||
// even when capturing is disabled. So, to enable detailed profiling for this class, define the
|
||||
// Profile_RenderTreeBuilder compiler symbol, otherwise the calls are compiled out entirely.
|
||||
// Enabling detailed profiling adds about 5% to rendering benchmark times.
|
||||
|
||||
[Conditional("Profile_RenderTreeBuilder")]
|
||||
private static void ProfilingStart([CallerMemberName] string? name = null)
|
||||
=> ComponentsProfiling.Instance.Start(name);
|
||||
|
||||
[Conditional("Profile_RenderTreeBuilder")]
|
||||
private static void ProfilingEnd([CallerMemberName] string? name = null)
|
||||
=> ComponentsProfiling.Instance.End(name);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
Thread capturedThread = null;
|
||||
|
||||
var e = new ManualResetEventSlim();
|
||||
|
||||
|
||||
// Act
|
||||
context.Post((_) =>
|
||||
{
|
||||
|
|
@ -766,7 +766,6 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
}
|
||||
|
||||
[Fact]
|
||||
[QuarantinedTest]
|
||||
public async Task InvokeAsync_SyncWorkInAsyncTaskIsCompletedFirst()
|
||||
{
|
||||
// Simplified version of ServerComponentRenderingTest.CanDispatchAsyncWorkToSyncContext
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
"WebAssembly\\Server\\test\\Microsoft.AspNetCore.Components.WebAssembly.Server.Tests.csproj",
|
||||
"WebAssembly\\WebAssembly.Authentication\\src\\Microsoft.AspNetCore.Components.WebAssembly.Authentication.csproj",
|
||||
"WebAssembly\\WebAssembly.Authentication\\test\\Microsoft.AspNetCore.Components.WebAssembly.Authentication.Tests.csproj",
|
||||
"WebAssembly\\WebAssemblyHttpHandler\\src\\Microsoft.AspNetCore.Components.WebAssembly.HttpHandler.csproj",
|
||||
"WebAssembly\\WebAssembly\\src\\Microsoft.AspNetCore.Components.WebAssembly.csproj",
|
||||
"WebAssembly\\WebAssembly\\test\\Microsoft.AspNetCore.Components.WebAssembly.Tests.csproj",
|
||||
"WebAssembly\\testassets\\HostedInAspNet.Client\\HostedInAspNet.Client.csproj",
|
||||
|
|
|
|||
|
|
@ -21,26 +21,4 @@
|
|||
</ItemGroup>
|
||||
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)..\, Directory.Build.targets))\Directory.Build.targets" />
|
||||
|
||||
<ItemGroup Condition="'$(FixupWebAssemblyHttpHandlerReference)' == 'true'">
|
||||
<ProjectReference
|
||||
Include="$(RepoRoot)src\Components\WebAssembly\WebAssemblyHttpHandler\src\Microsoft.AspNetCore.Components.WebAssembly.HttpHandler.csproj"
|
||||
CopyLocal="false" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="_FixupReferenceToWebAssemblyHttpHandler"
|
||||
Condition="'$(FixupWebAssemblyHttpHandlerReference)' == 'true'"
|
||||
AfterTargets="_ResolveBlazorInputs"
|
||||
BeforeTargets="_ResolveBlazorOutputs">
|
||||
<!--
|
||||
ProjectReference doesn't really play well with IncludeAssets behavior you get when referencing
|
||||
the package with IncludeAssets="compile".
|
||||
-->
|
||||
<ItemGroup>
|
||||
<_HttpHandlerAssembly Include="@(_BlazorUserRuntimeAssembly)"
|
||||
Condition="%(_BlazorUserRuntimeAssembly.ProjectReferenceOriginalItemSpec) == '$(RepoRoot)src\Components\WebAssembly\WebAssemblyHttpHandler\src\Microsoft.AspNetCore.Components.WebAssembly.HttpHandler.csproj'" />
|
||||
|
||||
<_BlazorUserRuntimeAssembly Remove="@(_HttpHandlerAssembly)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -64,7 +64,8 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
|
|||
_loggerFactory,
|
||||
_options,
|
||||
client,
|
||||
_loggerFactory.CreateLogger<RemoteRenderer>());
|
||||
_loggerFactory.CreateLogger<RemoteRenderer>(),
|
||||
jsRuntime.ElementReferenceContext);
|
||||
|
||||
var circuitHandlers = scope.ServiceProvider.GetServices<CircuitHandler>()
|
||||
.OrderBy(h => h.Order)
|
||||
|
|
|
|||
|
|
@ -17,12 +17,15 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
|
|||
private readonly ILogger<RemoteJSRuntime> _logger;
|
||||
private CircuitClientProxy _clientProxy;
|
||||
|
||||
public ElementReferenceContext ElementReferenceContext { get; }
|
||||
|
||||
public RemoteJSRuntime(IOptions<CircuitOptions> options, ILogger<RemoteJSRuntime> logger)
|
||||
{
|
||||
_options = options.Value;
|
||||
_logger = logger;
|
||||
DefaultAsyncTimeout = _options.JSInteropDefaultCallTimeout;
|
||||
JsonSerializerOptions.Converters.Add(new ElementReferenceJsonConverter());
|
||||
ElementReferenceContext = new WebElementReferenceContext(this);
|
||||
JsonSerializerOptions.Converters.Add(new ElementReferenceJsonConverter(ElementReferenceContext));
|
||||
}
|
||||
|
||||
internal void Initialize(CircuitClientProxy clientProxy)
|
||||
|
|
|
|||
|
|
@ -37,12 +37,15 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
|
|||
ILoggerFactory loggerFactory,
|
||||
CircuitOptions options,
|
||||
CircuitClientProxy client,
|
||||
ILogger logger)
|
||||
ILogger logger,
|
||||
ElementReferenceContext? elementReferenceContext)
|
||||
: base(serviceProvider, loggerFactory)
|
||||
{
|
||||
_client = client;
|
||||
_options = options;
|
||||
_logger = logger;
|
||||
|
||||
ElementReferenceContext = elementReferenceContext;
|
||||
}
|
||||
|
||||
public override Dispatcher Dispatcher { get; } = Dispatcher.CreateDefault();
|
||||
|
|
|
|||
|
|
@ -258,7 +258,13 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
|
|||
private class TestRemoteRenderer : RemoteRenderer
|
||||
{
|
||||
public TestRemoteRenderer(IServiceProvider serviceProvider, IClientProxy client)
|
||||
: base(serviceProvider, NullLoggerFactory.Instance, new CircuitOptions(), new CircuitClientProxy(client, "connection"), NullLogger.Instance)
|
||||
: base(
|
||||
serviceProvider,
|
||||
NullLoggerFactory.Instance,
|
||||
new CircuitOptions(),
|
||||
new CircuitClientProxy(client, "connection"),
|
||||
NullLogger.Instance,
|
||||
null)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -437,7 +437,7 @@ namespace Microsoft.AspNetCore.Components.Web.Rendering
|
|||
private class TestRemoteRenderer : RemoteRenderer
|
||||
{
|
||||
public TestRemoteRenderer(IServiceProvider serviceProvider, ILoggerFactory loggerFactory, CircuitOptions options, CircuitClientProxy client, ILogger logger)
|
||||
: base(serviceProvider, loggerFactory, options, client, logger)
|
||||
: base(serviceProvider, loggerFactory, options, client, logger, null)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,8 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
|
|||
NullLoggerFactory.Instance,
|
||||
new CircuitOptions(),
|
||||
clientProxy,
|
||||
NullLogger.Instance);
|
||||
NullLogger.Instance,
|
||||
null);
|
||||
}
|
||||
|
||||
handlers = handlers ?? Array.Empty<CircuitHandler>();
|
||||
|
|
|
|||
|
|
@ -1,22 +1,31 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components
|
||||
{
|
||||
public class ElementReferenceJsonConverterTest
|
||||
{
|
||||
private readonly ElementReferenceJsonConverter Converter = new ElementReferenceJsonConverter();
|
||||
private readonly ElementReferenceContext ElementReferenceContext;
|
||||
private readonly ElementReferenceJsonConverter Converter;
|
||||
|
||||
public ElementReferenceJsonConverterTest()
|
||||
{
|
||||
ElementReferenceContext = Mock.Of<ElementReferenceContext>();
|
||||
Converter = new ElementReferenceJsonConverter(ElementReferenceContext);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Serializing_Works()
|
||||
{
|
||||
// Arrange
|
||||
var elementReference = ElementReference.CreateWithUniqueId();
|
||||
var elementReference = ElementReference.CreateWithUniqueId(ElementReferenceContext);
|
||||
var expected = $"{{\"__internalId\":\"{elementReference.Id}\"}}";
|
||||
var memoryStream = new MemoryStream();
|
||||
var writer = new Utf8JsonWriter(memoryStream);
|
||||
|
|
@ -34,7 +43,7 @@ namespace Microsoft.AspNetCore.Components
|
|||
public void Deserializing_Works()
|
||||
{
|
||||
// Arrange
|
||||
var id = ElementReference.CreateWithUniqueId().Id;
|
||||
var id = ElementReference.CreateWithUniqueId(ElementReferenceContext).Id;
|
||||
var json = $"{{\"__internalId\":\"{id}\"}}";
|
||||
var bytes = Encoding.UTF8.GetBytes(json);
|
||||
var reader = new Utf8JsonReader(bytes);
|
||||
|
|
@ -51,7 +60,7 @@ namespace Microsoft.AspNetCore.Components
|
|||
public void Deserializing_WithFormatting_Works()
|
||||
{
|
||||
// Arrange
|
||||
var id = ElementReference.CreateWithUniqueId().Id;
|
||||
var id = ElementReference.CreateWithUniqueId(ElementReferenceContext).Id;
|
||||
var json =
|
||||
@$"{{
|
||||
""__internalId"": ""{id}""
|
||||
|
|
|
|||
|
|
@ -11,6 +11,13 @@ namespace Microsoft.AspNetCore.Components
|
|||
{
|
||||
private static readonly JsonEncodedText IdProperty = JsonEncodedText.Encode("__internalId");
|
||||
|
||||
private readonly ElementReferenceContext _elementReferenceContext;
|
||||
|
||||
public ElementReferenceJsonConverter(ElementReferenceContext elementReferenceContext)
|
||||
{
|
||||
_elementReferenceContext = elementReferenceContext;
|
||||
}
|
||||
|
||||
public override ElementReference Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
string id = null;
|
||||
|
|
@ -39,7 +46,7 @@ namespace Microsoft.AspNetCore.Components
|
|||
throw new JsonException("__internalId is required.");
|
||||
}
|
||||
|
||||
return new ElementReference(id);
|
||||
return new ElementReference(id, _elementReferenceContext);
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, ElementReference value, JsonSerializerOptions options)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace WebAssembly.JSInterop
|
||||
|
|
@ -21,6 +22,6 @@ namespace WebAssembly.JSInterop
|
|||
public static extern string InvokeJSMarshalled(out string exception, ref long asyncHandle, string functionIdentifier, string argsJson);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
public static extern TRes InvokeJSUnmarshalled<T0, T1, T2, TRes>(out string exception, string functionIdentifier, T0 arg0, T1 arg1, T2 arg2);
|
||||
public static extern TRes InvokeJSUnmarshalled<T0, T1, T2, TRes>(out string exception, string functionIdentifier, [AllowNull] T0 arg0, [AllowNull] T1 arg1, [AllowNull] T2 arg2);
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -12,6 +12,7 @@ import { setEventDispatcher } from './Rendering/RendererEventDispatcher';
|
|||
import { resolveOptions, CircuitStartOptions } from './Platform/Circuits/CircuitStartOptions';
|
||||
import { DefaultReconnectionHandler } from './Platform/Circuits/DefaultReconnectionHandler';
|
||||
import { attachRootComponentToLogicalElement } from './Rendering/Renderer';
|
||||
import { initializeProfiling } from './Platform/Profiling';
|
||||
|
||||
let renderingFailed = false;
|
||||
let started = false;
|
||||
|
|
@ -21,6 +22,7 @@ async function boot(userOptions?: Partial<CircuitStartOptions>): Promise<void> {
|
|||
throw new Error('Blazor has already started.');
|
||||
}
|
||||
started = true;
|
||||
initializeProfiling(null);
|
||||
|
||||
// Establish options to be used
|
||||
const options = resolveOptions(userOptions);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import { WebAssemblyConfigLoader } from './Platform/WebAssemblyConfigLoader';
|
|||
import { BootConfigResult } from './Platform/BootConfig';
|
||||
import { Pointer } from './Platform/Platform';
|
||||
import { WebAssemblyStartOptions } from './Platform/WebAssemblyStartOptions';
|
||||
import { profileStart, profileEnd } from './Platform/Profiling';
|
||||
|
||||
let started = false;
|
||||
|
||||
|
|
@ -27,7 +28,9 @@ async function boot(options?: Partial<WebAssemblyStartOptions>): Promise<void> {
|
|||
const platform = Environment.setPlatform(monoPlatform);
|
||||
window['Blazor'].platform = platform;
|
||||
window['Blazor']._internal.renderBatch = (browserRendererId: number, batchAddress: Pointer) => {
|
||||
profileStart('renderBatch');
|
||||
renderBatch(browserRendererId, new SharedMemoryRenderBatch(batchAddress));
|
||||
profileEnd('renderBatch');
|
||||
};
|
||||
|
||||
// Configure navigation via JS Interop
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
import '@microsoft/dotnet-js-interop';
|
||||
|
||||
export const domFunctions = {
|
||||
focus,
|
||||
};
|
||||
|
||||
function focus(element: HTMLElement): void {
|
||||
if (element instanceof HTMLElement) {
|
||||
element.focus();
|
||||
} else {
|
||||
throw new Error('Unable to focus an invalid element.');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
import { navigateTo, internalFunctions as navigationManagerInternalFunctions } from './Services/NavigationManager';
|
||||
import { attachRootComponentToElement } from './Rendering/Renderer';
|
||||
import { domFunctions } from './DomWrapper';
|
||||
import { setProfilingEnabled } from './Platform/Profiling';
|
||||
|
||||
// Make the following APIs available in global scope for invocation from JS
|
||||
window['Blazor'] = {
|
||||
|
|
@ -8,5 +10,7 @@ window['Blazor'] = {
|
|||
_internal: {
|
||||
attachRootComponentToElement,
|
||||
navigationManager: navigationManagerInternalFunctions,
|
||||
domWrapper: domFunctions,
|
||||
setProfilingEnabled: setProfilingEnabled,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { WebAssemblyResourceLoader, LoadingResource } from '../WebAssemblyResour
|
|||
import { Platform, System_Array, Pointer, System_Object, System_String } from '../Platform';
|
||||
import { loadTimezoneData } from './TimezoneDataFile';
|
||||
import { WebAssemblyBootResourceType } from '../WebAssemblyStartOptions';
|
||||
import { initializeProfiling } from '../Profiling';
|
||||
|
||||
let mono_string_get_utf8: (managedString: System_String) => Pointer;
|
||||
let mono_wasm_add_assembly: (name: string, heapAddress: number, length: number) => void;
|
||||
|
|
@ -34,6 +35,10 @@ export const monoPlatform: Platform = {
|
|||
start: function start(resourceLoader: WebAssemblyResourceLoader) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
attachDebuggerHotkey(resourceLoader);
|
||||
initializeProfiling(isCapturing => {
|
||||
const setCapturingMethod = bindStaticMethod('Microsoft.AspNetCore.Components', 'Microsoft.AspNetCore.Components.Profiling.WebAssemblyComponentsProfiling', 'SetCapturing');
|
||||
setCapturingMethod(isCapturing);
|
||||
});
|
||||
|
||||
// dotnet.js assumes the existence of this
|
||||
window['Browser'] = {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,134 @@
|
|||
import { System_String } from './Platform';
|
||||
|
||||
interface TimingEntry {
|
||||
// To minimize overhead, don't even decode the strings that arrive from .NET. Assume they are compile-time constants
|
||||
// and hence the memory address will be fixed, so we can just store the pointer value.
|
||||
name: string | System_String;
|
||||
type: 'start' | 'end';
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
interface TraceEvent {
|
||||
// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
|
||||
name: string;
|
||||
cat: string; // Category
|
||||
ph: 'B' | 'E'; // Phase
|
||||
ts: number; // Timestamp in microseconds
|
||||
pid: number; // Process ID
|
||||
tid: number; // Thread ID
|
||||
}
|
||||
|
||||
let updateCapturingStateInHost: (isCapturing: boolean) => void;
|
||||
let captureStartTime = 0;
|
||||
const blazorProfilingEnabledKey = 'blazorProfilingEnabled';
|
||||
const profilingEnabled = !!localStorage[blazorProfilingEnabledKey];
|
||||
const entryLog: TimingEntry[] = [];
|
||||
const openRegionsStack: (string | System_String)[] = [];
|
||||
|
||||
export function setProfilingEnabled(enabled: boolean) {
|
||||
// We only wire up the hotkeys etc. if the following localStorage entry is present during startup
|
||||
// This is to ensure we're not interfering with any other hotkeys that developers might want to
|
||||
// use for different purposes, plus it gives us a single point where we can notify .NET code during
|
||||
// startup about whether profiling should be enabled.
|
||||
localStorage[blazorProfilingEnabledKey] = (enabled !== false);
|
||||
location.reload();
|
||||
}
|
||||
|
||||
export function initializeProfiling(setCapturingCallback: ((isCapturing: boolean) => void) | null) {
|
||||
if (!profilingEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateCapturingStateInHost = setCapturingCallback || (() => {});
|
||||
|
||||
// Attach hotkey (alt/cmd)+shift+p
|
||||
const altKeyName = navigator.platform.match(/^Mac/i) ? 'Cmd' : 'Alt';
|
||||
console.info(`Profiling hotkey: Shift+${altKeyName}+P (when application has focus)`);
|
||||
document.addEventListener('keydown', evt => {
|
||||
if (evt.shiftKey && (evt.metaKey || evt.altKey) && evt.code === 'KeyP') {
|
||||
toggleCaptureEnabled();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function profileStart(name: System_String | string) {
|
||||
if (!captureStartTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
const startTime = performance.now();
|
||||
openRegionsStack.push(name);
|
||||
entryLog.push({ name: name, type: 'start', timestamp: startTime });
|
||||
}
|
||||
|
||||
export function profileEnd(name: System_String | string) {
|
||||
if (!captureStartTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
const endTime = performance.now();
|
||||
const poppedRegionName = openRegionsStack.pop();
|
||||
if (!poppedRegionName) {
|
||||
throw new Error(`Profiling mismatch: tried to end profiling for '${readJsString(name)}', but the stack was empty.`);
|
||||
} else if (poppedRegionName !== name) {
|
||||
throw new Error(`Profiling mismatch: tried to end profiling for '${readJsString(name)}', but the top stack item was '${readJsString(poppedRegionName)}'.`);
|
||||
}
|
||||
|
||||
entryLog.push({ name: name, type: 'end', timestamp: endTime });
|
||||
}
|
||||
|
||||
function profileReset() {
|
||||
openRegionsStack.length = 0;
|
||||
entryLog.length = 0;
|
||||
captureStartTime = 0;
|
||||
updateCapturingStateInHost(false);
|
||||
}
|
||||
|
||||
function profileExport() {
|
||||
const traceEvents: TraceEvent[] = entryLog.map(entry => ({
|
||||
name: readJsString(entry.name)!,
|
||||
cat: 'PERF',
|
||||
ph: entry.type === 'start' ? 'B': 'E',
|
||||
ts: (entry.timestamp - captureStartTime) * 1000,
|
||||
pid: 0,
|
||||
tid: 0,
|
||||
}));
|
||||
const traceEventsJson = JSON.stringify(traceEvents);
|
||||
const traceEventsBuffer = new TextEncoder().encode(traceEventsJson);
|
||||
const anchorElement = document.createElement('a');
|
||||
anchorElement.href = URL.createObjectURL(new Blob([traceEventsBuffer]));
|
||||
anchorElement.setAttribute('download', 'trace.json');
|
||||
anchorElement.click();
|
||||
URL.revokeObjectURL(anchorElement.href);
|
||||
}
|
||||
|
||||
function toggleCaptureEnabled() {
|
||||
if (!captureStartTime) {
|
||||
displayOverlayMessage('Started capturing performance profile...');
|
||||
updateCapturingStateInHost(true);
|
||||
captureStartTime = performance.now();
|
||||
} else {
|
||||
displayOverlayMessage('Finished capturing performance profile');
|
||||
profileExport();
|
||||
profileReset();
|
||||
}
|
||||
}
|
||||
|
||||
function displayOverlayMessage(message: string) {
|
||||
const elem = document.createElement('div');
|
||||
elem.textContent = message;
|
||||
elem.setAttribute('style', 'position: absolute; z-index: 99999; font-family: \'Sans Serif\'; top: 0; left: 0; padding: 4px; font-size: 12px; background-color: purple; color: white;');
|
||||
document.body.appendChild(elem);
|
||||
setTimeout(() => document.body.removeChild(elem), 3000);
|
||||
}
|
||||
|
||||
function readJsString(str: string | System_String) {
|
||||
// This is expensive, so don't do it while capturing timings. Only do it as part of the export process.
|
||||
return typeof str === 'string' ? str : BINDING.conv_string(str);
|
||||
}
|
||||
|
||||
// These globals deliberately differ from our normal conventions for attaching functions inside Blazor.*
|
||||
// because the intention is to minimize overhead in all reasonable ways. Having any dot-separators in the
|
||||
// name would cause extra string allocations on every invocation.
|
||||
window['_blazorProfileStart'] = profileStart;
|
||||
window['_blazorProfileEnd'] = profileEnd;
|
||||
|
|
@ -6,6 +6,7 @@ import { applyCaptureIdToElement } from './ElementReferenceCapture';
|
|||
import { EventFieldInfo } from './EventFieldInfo';
|
||||
import { dispatchEvent } from './RendererEventDispatcher';
|
||||
import { attachToEventDelegator as attachNavigationManagerToEventDelegator } from '../Services/NavigationManager';
|
||||
import { profileEnd, profileStart } from '../Platform/Profiling';
|
||||
const selectValuePropname = '_blazorSelectValue';
|
||||
const sharedTemplateElemForParsing = document.createElement('template');
|
||||
const sharedSvgElemForParsing = document.createElementNS('http://www.w3.org/2000/svg', 'g');
|
||||
|
|
@ -40,6 +41,8 @@ export class BrowserRenderer {
|
|||
}
|
||||
|
||||
public updateComponent(batch: RenderBatch, componentId: number, edits: ArrayBuilderSegment<RenderTreeEdit>, referenceFrames: ArrayValues<RenderTreeFrame>): void {
|
||||
profileStart('updateComponent');
|
||||
|
||||
const element = this.childComponentLocations[componentId];
|
||||
if (!element) {
|
||||
throw new Error(`No element is currently associated with component ${componentId}`);
|
||||
|
|
@ -67,6 +70,8 @@ export class BrowserRenderer {
|
|||
if ((activeElementBefore instanceof HTMLElement) && ownerDocument && ownerDocument.activeElement !== activeElementBefore) {
|
||||
activeElementBefore.focus();
|
||||
}
|
||||
|
||||
profileEnd('updateComponent');
|
||||
}
|
||||
|
||||
public disposeComponent(componentId: number) {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,14 @@ namespace Microsoft.AspNetCore.Components
|
|||
public string? Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
public string? ValueAttribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
}
|
||||
public static partial class ElementReferenceExtensions
|
||||
{
|
||||
public static System.Threading.Tasks.ValueTask FocusAsync(this Microsoft.AspNetCore.Components.ElementReference elementReference) { throw null; }
|
||||
}
|
||||
public partial class WebElementReferenceContext : Microsoft.AspNetCore.Components.ElementReferenceContext
|
||||
{
|
||||
public WebElementReferenceContext(Microsoft.JSInterop.IJSRuntime jsRuntime) { }
|
||||
}
|
||||
}
|
||||
namespace Microsoft.AspNetCore.Components.Forms
|
||||
{
|
||||
|
|
@ -53,7 +61,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
protected TValue CurrentValue { get { throw null; } set { } }
|
||||
protected string? CurrentValueAsString { get { throw null; } set { } }
|
||||
protected Microsoft.AspNetCore.Components.Forms.EditContext EditContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||
protected Microsoft.AspNetCore.Components.Forms.FieldIdentifier FieldIdentifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||
protected internal Microsoft.AspNetCore.Components.Forms.FieldIdentifier FieldIdentifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||
[Microsoft.AspNetCore.Components.ParameterAttribute]
|
||||
[System.Diagnostics.CodeAnalysis.MaybeNullAttribute]
|
||||
[System.Diagnostics.CodeAnalysis.AllowNullAttribute]
|
||||
|
|
@ -63,7 +71,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
[Microsoft.AspNetCore.Components.ParameterAttribute]
|
||||
public System.Linq.Expressions.Expression<System.Func<TValue>>? ValueExpression { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||
protected virtual void Dispose(bool disposing) { }
|
||||
protected virtual string? FormatValueAsString(TValue value) { throw null; }
|
||||
protected virtual string? FormatValueAsString([System.Diagnostics.CodeAnalysis.AllowNullAttribute] TValue value) { throw null; }
|
||||
public override System.Threading.Tasks.Task SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters) { throw null; }
|
||||
void System.IDisposable.Dispose() { }
|
||||
protected abstract bool TryParseValueFromString(string? value, [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] out TValue result, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(false)] out string? validationErrorMessage);
|
||||
|
|
@ -80,7 +88,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
[Microsoft.AspNetCore.Components.ParameterAttribute]
|
||||
public string ParsingErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { }
|
||||
protected override string FormatValueAsString(TValue value) { throw null; }
|
||||
protected override string FormatValueAsString([System.Diagnostics.CodeAnalysis.AllowNullAttribute] TValue value) { throw null; }
|
||||
protected override bool TryParseValueFromString(string? value, [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] out TValue result, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(false)] out string? validationErrorMessage) { throw null; }
|
||||
}
|
||||
public partial class InputNumber<TValue> : Microsoft.AspNetCore.Components.Forms.InputBase<TValue>
|
||||
|
|
@ -89,9 +97,34 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
[Microsoft.AspNetCore.Components.ParameterAttribute]
|
||||
public string ParsingErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { }
|
||||
protected override string? FormatValueAsString(TValue value) { throw null; }
|
||||
protected override string? FormatValueAsString([System.Diagnostics.CodeAnalysis.AllowNullAttribute] TValue value) { throw null; }
|
||||
protected override bool TryParseValueFromString(string? value, [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] out TValue result, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(false)] out string? validationErrorMessage) { throw null; }
|
||||
}
|
||||
public partial class InputRadioGroup<TValue> : Microsoft.AspNetCore.Components.Forms.InputBase<TValue>
|
||||
{
|
||||
public InputRadioGroup() { }
|
||||
[Microsoft.AspNetCore.Components.ParameterAttribute]
|
||||
public Microsoft.AspNetCore.Components.RenderFragment? ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||
[Microsoft.AspNetCore.Components.ParameterAttribute]
|
||||
public string? Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { }
|
||||
protected override void OnParametersSet() { }
|
||||
protected override bool TryParseValueFromString(string? value, [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] out TValue result, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(false)] out string? validationErrorMessage) { throw null; }
|
||||
}
|
||||
public partial class InputRadio<TValue> : Microsoft.AspNetCore.Components.ComponentBase
|
||||
{
|
||||
public InputRadio() { }
|
||||
[Microsoft.AspNetCore.Components.ParameterAttribute(CaptureUnmatchedValues=true)]
|
||||
public System.Collections.Generic.IReadOnlyDictionary<string, object>? AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||
[Microsoft.AspNetCore.Components.ParameterAttribute]
|
||||
public string? Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||
[Microsoft.AspNetCore.Components.ParameterAttribute]
|
||||
[System.Diagnostics.CodeAnalysis.MaybeNullAttribute]
|
||||
[System.Diagnostics.CodeAnalysis.AllowNullAttribute]
|
||||
public TValue Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { }
|
||||
protected override void OnParametersSet() { }
|
||||
}
|
||||
public partial class InputSelect<TValue> : Microsoft.AspNetCore.Components.Forms.InputBase<TValue>
|
||||
{
|
||||
public InputSelect() { }
|
||||
|
|
|
|||
|
|
@ -14,6 +14,14 @@ namespace Microsoft.AspNetCore.Components
|
|||
public string? Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
public string? ValueAttribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||
}
|
||||
public static partial class ElementReferenceExtensions
|
||||
{
|
||||
public static System.Threading.Tasks.ValueTask FocusAsync(this Microsoft.AspNetCore.Components.ElementReference elementReference) { throw null; }
|
||||
}
|
||||
public partial class WebElementReferenceContext : Microsoft.AspNetCore.Components.ElementReferenceContext
|
||||
{
|
||||
public WebElementReferenceContext(Microsoft.JSInterop.IJSRuntime jsRuntime) { }
|
||||
}
|
||||
}
|
||||
namespace Microsoft.AspNetCore.Components.Forms
|
||||
{
|
||||
|
|
@ -51,7 +59,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
protected TValue CurrentValue { get { throw null; } set { } }
|
||||
protected string? CurrentValueAsString { get { throw null; } set { } }
|
||||
protected Microsoft.AspNetCore.Components.Forms.EditContext EditContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||
protected Microsoft.AspNetCore.Components.Forms.FieldIdentifier FieldIdentifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||
protected internal Microsoft.AspNetCore.Components.Forms.FieldIdentifier FieldIdentifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||
[Microsoft.AspNetCore.Components.ParameterAttribute]
|
||||
public TValue Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||
[Microsoft.AspNetCore.Components.ParameterAttribute]
|
||||
|
|
@ -88,6 +96,29 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
protected override string? FormatValueAsString(TValue value) { throw null; }
|
||||
protected override bool TryParseValueFromString(string? value, out TValue result, out string? validationErrorMessage) { throw null; }
|
||||
}
|
||||
public partial class InputRadioGroup<TValue> : Microsoft.AspNetCore.Components.Forms.InputBase<TValue>
|
||||
{
|
||||
public InputRadioGroup() { }
|
||||
[Microsoft.AspNetCore.Components.ParameterAttribute]
|
||||
public Microsoft.AspNetCore.Components.RenderFragment? ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||
[Microsoft.AspNetCore.Components.ParameterAttribute]
|
||||
public string? Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { }
|
||||
protected override void OnParametersSet() { }
|
||||
protected override bool TryParseValueFromString(string? value, out TValue result, out string? validationErrorMessage) { throw null; }
|
||||
}
|
||||
public partial class InputRadio<TValue> : Microsoft.AspNetCore.Components.ComponentBase
|
||||
{
|
||||
public InputRadio() { }
|
||||
[Microsoft.AspNetCore.Components.ParameterAttribute(CaptureUnmatchedValues=true)]
|
||||
public System.Collections.Generic.IReadOnlyDictionary<string, object>? AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||
[Microsoft.AspNetCore.Components.ParameterAttribute]
|
||||
public string? Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||
[Microsoft.AspNetCore.Components.ParameterAttribute]
|
||||
public TValue Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { }
|
||||
protected override void OnParametersSet() { }
|
||||
}
|
||||
public partial class InputSelect<TValue> : Microsoft.AspNetCore.Components.Forms.InputBase<TValue>
|
||||
{
|
||||
public InputSelect() { }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNetCore.Components
|
||||
{
|
||||
internal static class DomWrapperInterop
|
||||
{
|
||||
private const string Prefix = "Blazor._internal.domWrapper.";
|
||||
|
||||
public const string Focus = Prefix + "focus";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components
|
||||
{
|
||||
public static class ElementReferenceExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gives focus to an element given its <see cref="ElementReference"/>.
|
||||
/// </summary>
|
||||
/// <param name="elementReference">A reference to the element to focus.</param>
|
||||
/// <returns>The <see cref="ValueTask"/> representing the asynchronous focus operation.</returns>
|
||||
public static ValueTask FocusAsync(this ElementReference elementReference)
|
||||
{
|
||||
var jsRuntime = elementReference.GetJSRuntime();
|
||||
|
||||
if (jsRuntime == null)
|
||||
{
|
||||
throw new InvalidOperationException("No JavaScript runtime found.");
|
||||
}
|
||||
|
||||
return jsRuntime.InvokeVoidAsync(DomWrapperInterop.Focus, elementReference);
|
||||
}
|
||||
|
||||
internal static IJSRuntime GetJSRuntime(this ElementReference elementReference)
|
||||
{
|
||||
if (!(elementReference.Context is WebElementReferenceContext context))
|
||||
{
|
||||
throw new InvalidOperationException("ElementReference has not been configured correctly.");
|
||||
}
|
||||
|
||||
return context.JSRuntime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -58,7 +58,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
/// <summary>
|
||||
/// Gets the <see cref="FieldIdentifier"/> for the bound value.
|
||||
/// </summary>
|
||||
protected FieldIdentifier FieldIdentifier { get; set; }
|
||||
protected internal FieldIdentifier FieldIdentifier { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current value of the input.
|
||||
|
|
@ -142,7 +142,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
/// </summary>
|
||||
/// <param name="value">The value to format.</param>
|
||||
/// <returns>A string representation of the value.</returns>
|
||||
protected virtual string? FormatValueAsString(TValue value)
|
||||
protected virtual string? FormatValueAsString([AllowNull] TValue value)
|
||||
=> value?.ToString();
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override string FormatValueAsString(TValue value)
|
||||
protected override string FormatValueAsString([AllowNull] TValue value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.Forms
|
||||
{
|
||||
internal static class InputExtensions
|
||||
{
|
||||
public static bool TryParseSelectableValueFromString<TValue>(this InputBase<TValue> input, string? value, [MaybeNull] out TValue result, [NotNullWhen(false)] out string? validationErrorMessage)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (BindConverter.TryConvertTo<TValue>(value, CultureInfo.CurrentCulture, out var parsedValue))
|
||||
{
|
||||
result = parsedValue;
|
||||
validationErrorMessage = null;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = default;
|
||||
validationErrorMessage = $"The {input.FieldIdentifier.FieldName} field is not valid.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
throw new InvalidOperationException($"{input.GetType()} does not support the type '{typeof(TValue)}'.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
/// </summary>
|
||||
/// <param name="value">The value to format.</param>
|
||||
/// <returns>A string representation of the value.</returns>
|
||||
protected override string? FormatValueAsString(TValue value)
|
||||
protected override string? FormatValueAsString([AllowNull] TValue value)
|
||||
{
|
||||
// Avoiding a cast to IFormattable to avoid boxing.
|
||||
switch (value)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.AspNetCore.Components.Rendering;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// An input component used for selecting a value from a group of choices.
|
||||
/// </summary>
|
||||
public class InputRadio<TValue> : ComponentBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets context for this <see cref="InputRadio{TValue}"/>.
|
||||
/// </summary>
|
||||
internal InputRadioContext? Context { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a collection of additional attributes that will be applied to the input element.
|
||||
/// </summary>
|
||||
[Parameter(CaptureUnmatchedValues = true)] public IReadOnlyDictionary<string, object>? AdditionalAttributes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value of this input.
|
||||
/// </summary>
|
||||
[AllowNull]
|
||||
[MaybeNull]
|
||||
[Parameter]
|
||||
public TValue Value { get; set; } = default;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the parent input radio group.
|
||||
/// </summary>
|
||||
[Parameter] public string? Name { get; set; }
|
||||
|
||||
[CascadingParameter] private InputRadioContext? CascadedContext { get; set; }
|
||||
|
||||
private string GetCssClass(string fieldClass)
|
||||
{
|
||||
if (AdditionalAttributes != null &&
|
||||
AdditionalAttributes.TryGetValue("class", out var @class) &&
|
||||
!string.IsNullOrEmpty(Convert.ToString(@class)))
|
||||
{
|
||||
return $"{@class} {fieldClass}";
|
||||
}
|
||||
|
||||
return fieldClass;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
Context = string.IsNullOrEmpty(Name) ? CascadedContext : CascadedContext?.FindContextInAncestors(Name);
|
||||
|
||||
if (Context == null)
|
||||
{
|
||||
throw new InvalidOperationException($"{GetType()} must have an ancestor {typeof(InputRadioGroup<TValue>)} " +
|
||||
$"with a matching 'Name' property, if specified.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void BuildRenderTree(RenderTreeBuilder builder)
|
||||
{
|
||||
Debug.Assert(Context != null);
|
||||
|
||||
builder.OpenElement(0, "input");
|
||||
builder.AddMultipleAttributes(1, AdditionalAttributes);
|
||||
builder.AddAttribute(2, "class", GetCssClass(Context.FieldClass));
|
||||
builder.AddAttribute(3, "type", "radio");
|
||||
builder.AddAttribute(4, "name", Context.GroupName);
|
||||
builder.AddAttribute(5, "value", BindConverter.FormatValue(Value?.ToString()));
|
||||
builder.AddAttribute(6, "checked", Context.CurrentValue?.Equals(Value));
|
||||
builder.AddAttribute(7, "onchange", Context.ChangeEventCallback);
|
||||
builder.CloseElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes context for an <see cref="InputRadio{TValue}"/> component.
|
||||
/// </summary>
|
||||
internal class InputRadioContext
|
||||
{
|
||||
private readonly InputRadioContext? _parentContext;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the input radio group.
|
||||
/// </summary>
|
||||
public string GroupName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current selected value in the input radio group.
|
||||
/// </summary>
|
||||
public object? CurrentValue { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a css class indicating the validation state of input radio elements.
|
||||
/// </summary>
|
||||
public string FieldClass { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the event callback to be invoked when the selected value is changed.
|
||||
/// </summary>
|
||||
public EventCallback<ChangeEventArgs> ChangeEventCallback { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates a new <see cref="InputRadioContext" />.
|
||||
/// </summary>
|
||||
/// <param name="parentContext">The parent <see cref="InputRadioContext" />.</param>
|
||||
/// <param name="groupName">The name of the input radio group.</param>
|
||||
/// <param name="currentValue">The current selected value in the input radio group.</param>
|
||||
/// <param name="fieldClass">The css class indicating the validation state of input radio elements.</param>
|
||||
/// <param name="changeEventCallback">The event callback to be invoked when the selected value is changed.</param>
|
||||
public InputRadioContext(
|
||||
InputRadioContext? parentContext,
|
||||
string groupName,
|
||||
object? currentValue,
|
||||
string fieldClass,
|
||||
EventCallback<ChangeEventArgs> changeEventCallback)
|
||||
{
|
||||
_parentContext = parentContext;
|
||||
|
||||
GroupName = groupName;
|
||||
CurrentValue = currentValue;
|
||||
FieldClass = fieldClass;
|
||||
ChangeEventCallback = changeEventCallback;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds an <see cref="InputRadioContext"/> in the context's ancestors with the matching <paramref name="groupName"/>.
|
||||
/// </summary>
|
||||
/// <param name="groupName">The group name of the ancestor <see cref="InputRadioContext"/>.</param>
|
||||
/// <returns>The <see cref="InputRadioContext"/>, or <c>null</c> if none was found.</returns>
|
||||
public InputRadioContext? FindContextInAncestors(string groupName)
|
||||
=> string.Equals(GroupName, groupName) ? this : _parentContext?.FindContextInAncestors(groupName);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.AspNetCore.Components.Rendering;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// Groups child <see cref="InputRadio{TValue}"/> components.
|
||||
/// </summary>
|
||||
public class InputRadioGroup<TValue> : InputBase<TValue>
|
||||
{
|
||||
private readonly string _defaultGroupName = Guid.NewGuid().ToString("N");
|
||||
private InputRadioContext? _context;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the child content to be rendering inside the <see cref="InputRadioGroup{TValue}"/>.
|
||||
/// </summary>
|
||||
[Parameter] public RenderFragment? ChildContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the group.
|
||||
/// </summary>
|
||||
[Parameter] public string? Name { get; set; }
|
||||
|
||||
[CascadingParameter] private InputRadioContext? CascadedContext { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
var groupName = !string.IsNullOrEmpty(Name) ? Name : _defaultGroupName;
|
||||
var fieldClass = EditContext.FieldCssClass(FieldIdentifier);
|
||||
var changeEventCallback = EventCallback.Factory.CreateBinder<string?>(this, __value => CurrentValueAsString = __value, CurrentValueAsString);
|
||||
|
||||
_context = new InputRadioContext(CascadedContext, groupName, CurrentValue, fieldClass, changeEventCallback);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void BuildRenderTree(RenderTreeBuilder builder)
|
||||
{
|
||||
Debug.Assert(_context != null);
|
||||
|
||||
builder.OpenComponent<CascadingValue<InputRadioContext>>(2);
|
||||
builder.AddAttribute(3, "IsFixed", true);
|
||||
builder.AddAttribute(4, "Value", _context);
|
||||
builder.AddAttribute(5, "ChildContent", ChildContent);
|
||||
builder.CloseComponent();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override bool TryParseValueFromString(string? value, [MaybeNull] out TValue result, [NotNullWhen(false)] out string? validationErrorMessage)
|
||||
=> this.TryParseSelectableValueFromString(value, out result, out validationErrorMessage);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,7 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNetCore.Components.Rendering;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.Forms
|
||||
|
|
@ -13,8 +11,6 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
/// </summary>
|
||||
public class InputSelect<TValue> : InputBase<TValue>
|
||||
{
|
||||
private static readonly Type? _nullableUnderlyingType = Nullable.GetUnderlyingType(typeof(TValue));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the child content to be rendering inside the select element.
|
||||
/// </summary>
|
||||
|
|
@ -34,31 +30,6 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
|
||||
/// <inheritdoc />
|
||||
protected override bool TryParseValueFromString(string? value, [MaybeNull] out TValue result, [NotNullWhen(false)] out string? validationErrorMessage)
|
||||
{
|
||||
if (typeof(TValue) == typeof(string))
|
||||
{
|
||||
result = (TValue)(object?)value;
|
||||
validationErrorMessage = null;
|
||||
return true;
|
||||
}
|
||||
else if (typeof(TValue).IsEnum || (_nullableUnderlyingType != null && _nullableUnderlyingType.IsEnum))
|
||||
{
|
||||
var success = BindConverter.TryConvertTo<TValue>(value, CultureInfo.CurrentCulture, out var parsedValue);
|
||||
if (success)
|
||||
{
|
||||
result = parsedValue;
|
||||
validationErrorMessage = null;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = default;
|
||||
validationErrorMessage = $"The {FieldIdentifier.FieldName} field is not valid.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"{GetType()} does not support the type '{typeof(TValue)}'.");
|
||||
}
|
||||
=> this.TryParseSelectableValueFromString(value, out result, out validationErrorMessage);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Components.Server.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Components.Web.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components
|
||||
{
|
||||
public class WebElementReferenceContext : ElementReferenceContext
|
||||
{
|
||||
internal IJSRuntime JSRuntime { get; }
|
||||
|
||||
public WebElementReferenceContext(IJSRuntime jsRuntime)
|
||||
{
|
||||
JSRuntime = jsRuntime ?? throw new ArgumentNullException(nameof(jsRuntime));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components.Rendering;
|
||||
using Microsoft.AspNetCore.Components.RenderTree;
|
||||
using Microsoft.AspNetCore.Components.Test.Helpers;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.Forms
|
||||
{
|
||||
public class InputRadioTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task ThrowsOnFirstRenderIfInputRadioHasNoGroup()
|
||||
{
|
||||
var model = new TestModel();
|
||||
var rootComponent = new TestInputRadioHostComponent<TestEnum>
|
||||
{
|
||||
EditContext = new EditContext(model),
|
||||
InnerContent = RadioButtonsWithoutGroup(null)
|
||||
};
|
||||
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => RenderAndGetTestInputComponentAsync(rootComponent));
|
||||
Assert.Contains($"must have an ancestor", ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GroupGeneratesNameGuidWhenInvalidNameSupplied()
|
||||
{
|
||||
var model = new TestModel();
|
||||
var rootComponent = new TestInputRadioHostComponent<TestEnum>
|
||||
{
|
||||
EditContext = new EditContext(model),
|
||||
InnerContent = RadioButtonsWithGroup(null, () => model.TestEnum)
|
||||
};
|
||||
|
||||
var inputRadioComponents = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
|
||||
Assert.All(inputRadioComponents, inputRadio => Assert.True(Guid.TryParseExact(inputRadio.GroupName, "N", out _)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RadioInputContextExistsWhenValidNameSupplied()
|
||||
{
|
||||
var groupName = "group";
|
||||
var model = new TestModel();
|
||||
var rootComponent = new TestInputRadioHostComponent<TestEnum>
|
||||
{
|
||||
EditContext = new EditContext(model),
|
||||
InnerContent = RadioButtonsWithGroup(groupName, () => model.TestEnum)
|
||||
};
|
||||
|
||||
var inputRadioComponents = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
|
||||
Assert.All(inputRadioComponents, inputRadio => Assert.Equal(groupName, inputRadio.GroupName));
|
||||
}
|
||||
|
||||
private static RenderFragment RadioButtonsWithoutGroup(string name) => (builder) =>
|
||||
{
|
||||
foreach (var selectedValue in (TestEnum[])Enum.GetValues(typeof(TestEnum)))
|
||||
{
|
||||
builder.OpenComponent<TestInputRadio>(0);
|
||||
builder.AddAttribute(1, "Name", name);
|
||||
builder.AddAttribute(2, "Value", selectedValue);
|
||||
builder.CloseComponent();
|
||||
}
|
||||
};
|
||||
|
||||
private static RenderFragment RadioButtonsWithGroup(string name, Expression<Func<TestEnum>> valueExpression) => (builder) =>
|
||||
{
|
||||
builder.OpenComponent<InputRadioGroup<TestEnum>>(0);
|
||||
builder.AddAttribute(1, "Name", name);
|
||||
builder.AddAttribute(2, "ValueExpression", valueExpression);
|
||||
builder.AddAttribute(2, "ChildContent", new RenderFragment((childBuilder) =>
|
||||
{
|
||||
foreach (var value in (TestEnum[])Enum.GetValues(typeof(TestEnum)))
|
||||
{
|
||||
childBuilder.OpenComponent<TestInputRadio>(0);
|
||||
childBuilder.AddAttribute(1, "Value", value);
|
||||
childBuilder.CloseComponent();
|
||||
}
|
||||
}));
|
||||
|
||||
builder.CloseComponent();
|
||||
};
|
||||
|
||||
private static IEnumerable<TestInputRadio> FindInputRadioComponents(CapturedBatch batch)
|
||||
=> batch.ReferenceFrames
|
||||
.Where(f => f.FrameType == RenderTreeFrameType.Component)
|
||||
.Select(f => f.Component)
|
||||
.OfType<TestInputRadio>();
|
||||
|
||||
private static async Task<IEnumerable<TestInputRadio>> RenderAndGetTestInputComponentAsync(TestInputRadioHostComponent<TestEnum> rootComponent)
|
||||
{
|
||||
var testRenderer = new TestRenderer();
|
||||
var componentId = testRenderer.AssignRootComponentId(rootComponent);
|
||||
await testRenderer.RenderRootComponentAsync(componentId);
|
||||
return FindInputRadioComponents(testRenderer.Batches.Single());
|
||||
}
|
||||
|
||||
private enum TestEnum
|
||||
{
|
||||
One,
|
||||
Two,
|
||||
Three
|
||||
}
|
||||
|
||||
private class TestModel
|
||||
{
|
||||
public TestEnum TestEnum { get; set; }
|
||||
}
|
||||
|
||||
private class TestInputRadio : InputRadio<TestEnum>
|
||||
{
|
||||
public string GroupName => Context.GroupName;
|
||||
}
|
||||
|
||||
private class TestInputRadioHostComponent<TValue> : AutoRenderComponent
|
||||
{
|
||||
public EditContext EditContext { get; set; }
|
||||
|
||||
public RenderFragment InnerContent { get; set; }
|
||||
|
||||
protected override void BuildRenderTree(RenderTreeBuilder builder)
|
||||
{
|
||||
builder.OpenComponent<CascadingValue<EditContext>>(0);
|
||||
builder.AddAttribute(1, "Value", EditContext);
|
||||
builder.AddAttribute(2, "ChildContent", InnerContent);
|
||||
builder.CloseComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -90,6 +90,88 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
Assert.Null(inputSelectComponent.CurrentValue);
|
||||
}
|
||||
|
||||
// See: https://github.com/dotnet/aspnetcore/issues/9939
|
||||
[Fact]
|
||||
public async Task ParsesCurrentValueWhenUsingNotNullableGuid()
|
||||
{
|
||||
// Arrange
|
||||
var model = new TestModel();
|
||||
var rootComponent = new TestInputSelectHostComponent<Guid>
|
||||
{
|
||||
EditContext = new EditContext(model),
|
||||
ValueExpression = () => model.NotNullableGuid
|
||||
};
|
||||
var inputSelectComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
|
||||
// Act
|
||||
var guid = Guid.NewGuid();
|
||||
inputSelectComponent.CurrentValueAsString = guid.ToString();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(guid, inputSelectComponent.CurrentValue);
|
||||
}
|
||||
|
||||
// See: https://github.com/dotnet/aspnetcore/issues/9939
|
||||
[Fact]
|
||||
public async Task ParsesCurrentValueWhenUsingNullableGuid()
|
||||
{
|
||||
// Arrange
|
||||
var model = new TestModel();
|
||||
var rootComponent = new TestInputSelectHostComponent<Guid?>
|
||||
{
|
||||
EditContext = new EditContext(model),
|
||||
ValueExpression = () => model.NullableGuid
|
||||
};
|
||||
var inputSelectComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
|
||||
// Act
|
||||
var guid = Guid.NewGuid();
|
||||
inputSelectComponent.CurrentValueAsString = guid.ToString();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(guid, inputSelectComponent.CurrentValue);
|
||||
}
|
||||
|
||||
// See: https://github.com/dotnet/aspnetcore/pull/19562
|
||||
[Fact]
|
||||
public async Task ParsesCurrentValueWhenUsingNotNullableInt()
|
||||
{
|
||||
// Arrange
|
||||
var model = new TestModel();
|
||||
var rootComponent = new TestInputSelectHostComponent<int>
|
||||
{
|
||||
EditContext = new EditContext(model),
|
||||
ValueExpression = () => model.NotNullableInt
|
||||
};
|
||||
var inputSelectComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
|
||||
// Act
|
||||
inputSelectComponent.CurrentValueAsString = "42";
|
||||
|
||||
// Assert
|
||||
Assert.Equal(42, inputSelectComponent.CurrentValue);
|
||||
}
|
||||
|
||||
// See: https://github.com/dotnet/aspnetcore/pull/19562
|
||||
[Fact]
|
||||
public async Task ParsesCurrentValueWhenUsingNullableInt()
|
||||
{
|
||||
// Arrange
|
||||
var model = new TestModel();
|
||||
var rootComponent = new TestInputSelectHostComponent<int?>
|
||||
{
|
||||
EditContext = new EditContext(model),
|
||||
ValueExpression = () => model.NullableInt
|
||||
};
|
||||
var inputSelectComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
|
||||
// Act
|
||||
inputSelectComponent.CurrentValueAsString = "42";
|
||||
|
||||
// Assert
|
||||
Assert.Equal(42, inputSelectComponent.CurrentValue);
|
||||
}
|
||||
|
||||
private static TestInputSelect<TValue> FindInputSelectComponent<TValue>(CapturedBatch batch)
|
||||
=> batch.ReferenceFrames
|
||||
.Where(f => f.FrameType == RenderTreeFrameType.Component)
|
||||
|
|
@ -117,6 +199,14 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
public TestEnum NotNullableEnum { get; set; }
|
||||
|
||||
public TestEnum? NullableEnum { get; set; }
|
||||
|
||||
public Guid NotNullableGuid { get; set; }
|
||||
|
||||
public Guid? NullableGuid { get; set; }
|
||||
|
||||
public int NotNullableInt { get; set; }
|
||||
|
||||
public int? NullableInt { get; set; }
|
||||
}
|
||||
|
||||
class TestInputSelect<TValue> : InputSelect<TValue>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="$(ComponentsSharedSourceRoot)src\WebAssemblyJSInteropInternalCalls.cs" />
|
||||
<Reference Include="Microsoft.JSInterop" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Authentication
|
|||
var parameters = ParameterView.FromDictionary(new Dictionary<string, object>
|
||||
{
|
||||
[_action] = RemoteAuthenticationActions.LogInCallback,
|
||||
[_onLogInSucceded] = new EventCallbackFactory().Create< RemoteAuthenticationState>(
|
||||
[_onLogInSucceded] = new EventCallbackFactory().Create<RemoteAuthenticationState>(
|
||||
remoteAuthenticator,
|
||||
(state) => loggingSucceededCalled = true),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -23,11 +23,6 @@
|
|||
Private="false"
|
||||
Condition="'$(BuildNodeJS)' != 'false' and '$(BuildingInsideVisualStudio)' != 'true'" />
|
||||
|
||||
<!-- Tracking removing using https://github.com/dotnet/aspnetcore/issues/22283 -->
|
||||
<ProjectReference
|
||||
Include="..\..\WebAssemblyHttpHandler\src\Microsoft.AspNetCore.Components.WebAssembly.HttpHandler.csproj"
|
||||
IncludeAssets="compile" />
|
||||
|
||||
<SuppressBaselineReference Include="Microsoft.AspNetCore.Components.WebAssembly.HttpHandler" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Rendering
|
|||
// The WebAssembly renderer registers and unregisters itself with the static registry
|
||||
_webAssemblyRendererId = RendererRegistry.Add(this);
|
||||
_logger = loggerFactory.CreateLogger<WebAssemblyRenderer>();
|
||||
|
||||
ElementReferenceContext = DefaultWebAssemblyJSRuntime.Instance.ElementReferenceContext;
|
||||
}
|
||||
|
||||
public override Dispatcher Dispatcher => NullDispatcher.Instance;
|
||||
|
|
|
|||
|
|
@ -10,9 +10,12 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Services
|
|||
{
|
||||
internal static readonly DefaultWebAssemblyJSRuntime Instance = new DefaultWebAssemblyJSRuntime();
|
||||
|
||||
public ElementReferenceContext ElementReferenceContext { get; }
|
||||
|
||||
private DefaultWebAssemblyJSRuntime()
|
||||
{
|
||||
JsonSerializerOptions.Converters.Add(new ElementReferenceJsonConverter());
|
||||
ElementReferenceContext = new WebElementReferenceContext(this);
|
||||
JsonSerializerOptions.Converters.Add(new ElementReferenceJsonConverter(ElementReferenceContext));
|
||||
}
|
||||
|
||||
#pragma warning disable IDE0051 // Remove unused private members. Invoked via Mono's JS interop mechanism (invoke_method)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Blazor.Rendering
|
||||
namespace Microsoft.AspNetCore.Components.WebAssembly.Rendering
|
||||
{
|
||||
public class RenderRegistryTest
|
||||
{
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<NuspecFile>$(MSBuildProjectName).nuspec</NuspecFile>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<PackageId>$(MSBuildProjectName)</PackageId>
|
||||
<AssemblyName>System.Net.Http.WebAssemblyHttpHandler</AssemblyName>
|
||||
<AssemblyVersion>0.2.2.0</AssemblyVersion>
|
||||
<ProduceOnlyReferenceAssembly>true</ProduceOnlyReferenceAssembly>
|
||||
<StrongNameKeyId>Open</StrongNameKeyId>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<NuspecProperty Include="OutputPath=$(OutputPath)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
using System;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace System.Net.Http
|
||||
{
|
||||
public partial class WebAssemblyHttpHandler : System.Net.Http.HttpMessageHandler
|
||||
{
|
||||
public WebAssemblyHttpHandler() { }
|
||||
protected override System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { throw null; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
|
||||
<metadata>
|
||||
$CommonMetadataElements$
|
||||
<dependencies>
|
||||
<group targetFramework=".NETStandard2.1" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
$CommonFileElements$
|
||||
<file src="$OutputPath$System.Net.Http.WebAssemblyHttpHandler.dll" target="lib\netstandard2.1\System.Net.Http.WebAssemblyHttpHandler.dll" />
|
||||
</files>
|
||||
</package>
|
||||
|
|
@ -4,8 +4,6 @@
|
|||
<TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
|
||||
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
|
||||
<UseBlazorWebAssembly>true</UseBlazorWebAssembly>
|
||||
|
||||
<FixupWebAssemblyHttpHandlerReference>true</FixupWebAssemblyHttpHandlerReference>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@
|
|||
<TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
|
||||
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
|
||||
<UseBlazorWebAssembly>true</UseBlazorWebAssembly>
|
||||
|
||||
<FixupWebAssemblyHttpHandlerReference>true</FixupWebAssemblyHttpHandlerReference>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -40,13 +40,12 @@ namespace Wasm.Performance.Driver
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (stressRunSeconds < 1)
|
||||
if (stressRunSeconds < 0)
|
||||
{
|
||||
Console.Error.WriteLine("Stress run duration must be a positive integer.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (stressRunSeconds > 0)
|
||||
else if (stressRunSeconds > 0)
|
||||
{
|
||||
isStressRun = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,13 @@ namespace Wasm.Performance.Driver
|
|||
{
|
||||
const int SeleniumPort = 4444;
|
||||
static bool RunHeadlessBrowser = true;
|
||||
static bool PoolForBrowserLogs = false;
|
||||
|
||||
static bool PoolForBrowserLogs =
|
||||
#if DEBUG
|
||||
true;
|
||||
#else
|
||||
false;
|
||||
#endif
|
||||
|
||||
private static async ValueTask<Uri> WaitForServerAsync(int port, CancellationToken cancellationToken)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
<!-- WebDriver is not strong-named, so this test project cannot be strong named either. -->
|
||||
<SignAssembly>false</SignAssembly>
|
||||
<IsTestAssetProject>true</IsTestAssetProject>
|
||||
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ The TestApp is a regular BlazorWASM project and can be run using `dotnet run`. T
|
|||
|
||||
Here are the commands you would need to run it locally inside docker:
|
||||
|
||||
1. `dotnet publish -c Release -r linux-x64 Driver/Wasm.Performance.Driver.csproj`
|
||||
1. `dotnet publish -c Release Driver/Wasm.Performance.Driver.csproj`
|
||||
2. `docker build -t blazor-local -f ./local.dockerfile . `
|
||||
3. `docker run -it blazor-local`
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,122 @@
|
|||
@page "/gridrendering"
|
||||
@inject IJSRuntime JSRuntime
|
||||
@using Wasm.Performance.TestApp.Shared.FastGrid
|
||||
|
||||
<h1>20 x 200 Grid</h1>
|
||||
|
||||
<fieldset>
|
||||
<select id="render-mode" @bind="selectedRenderMode">
|
||||
<option>@RenderMode.FastGrid</option>
|
||||
<option>@RenderMode.PlainTable</option>
|
||||
<option>@RenderMode.ComplexTable</option>
|
||||
</select>
|
||||
|
||||
<button id="show" @onclick="Show">Show</button>
|
||||
<button id="hide" @onclick="Hide">Hide</button>
|
||||
@if (forecasts != null)
|
||||
{
|
||||
<button id="change-page" @onclick="ChangePage">Switch pages</button>
|
||||
}
|
||||
</fieldset>
|
||||
|
||||
@if (forecasts == null)
|
||||
{
|
||||
<p><em>(No data assigned)</em></p>
|
||||
}
|
||||
else if (selectedRenderMode == RenderMode.FastGrid)
|
||||
{
|
||||
<p>FastGrid represents a minimal, optimized implementation of a grid.</p>
|
||||
|
||||
<Grid Data="@forecasts">
|
||||
<GridColumn TRowData="WeatherForecast" Title="Date">@context.Date.ToShortDateString()</GridColumn>
|
||||
<GridColumn TRowData="WeatherForecast" Title="TemperatureC">@context.TemperatureC</GridColumn>
|
||||
<GridColumn TRowData="WeatherForecast" Title="TemperatureF">@context.TemperatureF</GridColumn>
|
||||
<GridColumn TRowData="WeatherForecast" Title="Summary">@context.Summary</GridColumn>
|
||||
<GridColumn TRowData="WeatherForecast" Title="Date">@context.Date.ToShortDateString()</GridColumn>
|
||||
<GridColumn TRowData="WeatherForecast" Title="TemperatureC">@context.TemperatureC</GridColumn>
|
||||
<GridColumn TRowData="WeatherForecast" Title="TemperatureF">@context.TemperatureF</GridColumn>
|
||||
<GridColumn TRowData="WeatherForecast" Title="Summary">@context.Summary</GridColumn>
|
||||
<GridColumn TRowData="WeatherForecast" Title="Date">@context.Date.ToShortDateString()</GridColumn>
|
||||
<GridColumn TRowData="WeatherForecast" Title="TemperatureC">@context.TemperatureC</GridColumn>
|
||||
<GridColumn TRowData="WeatherForecast" Title="TemperatureF">@context.TemperatureF</GridColumn>
|
||||
<GridColumn TRowData="WeatherForecast" Title="Summary">@context.Summary</GridColumn>
|
||||
<GridColumn TRowData="WeatherForecast" Title="Date">@context.Date.ToShortDateString()</GridColumn>
|
||||
<GridColumn TRowData="WeatherForecast" Title="TemperatureC">@context.TemperatureC</GridColumn>
|
||||
<GridColumn TRowData="WeatherForecast" Title="TemperatureF">@context.TemperatureF</GridColumn>
|
||||
<GridColumn TRowData="WeatherForecast" Title="Summary">@context.Summary</GridColumn>
|
||||
<GridColumn TRowData="WeatherForecast" Title="Date">@context.Date.ToShortDateString()</GridColumn>
|
||||
<GridColumn TRowData="WeatherForecast" Title="TemperatureC">@context.TemperatureC</GridColumn>
|
||||
<GridColumn TRowData="WeatherForecast" Title="TemperatureF">@context.TemperatureF</GridColumn>
|
||||
<GridColumn TRowData="WeatherForecast" Title="Summary">@context.Summary</GridColumn>
|
||||
</Grid>
|
||||
}
|
||||
else if (selectedRenderMode == RenderMode.PlainTable)
|
||||
{
|
||||
<p>PlainTable represents a minimal but not optimized implementation of a grid.</p>
|
||||
|
||||
<Wasm.Performance.TestApp.Shared.PlainTable.TableComponent Data="@forecasts" Columns="@Columns" />
|
||||
}
|
||||
else if (selectedRenderMode == RenderMode.ComplexTable)
|
||||
{
|
||||
<p>ComplexTable represents a maximal, not optimized implementation of a grid, using a wide range of Blazor features at once.</p>
|
||||
|
||||
<Wasm.Performance.TestApp.Shared.ComplexTable.TableComponent Data="@forecasts" Columns="@Columns" />
|
||||
}
|
||||
|
||||
@code {
|
||||
enum RenderMode { PlainTable, ComplexTable, FastGrid }
|
||||
|
||||
private RenderMode selectedRenderMode = RenderMode.FastGrid;
|
||||
|
||||
private WeatherForecast[] forecasts;
|
||||
public List<string> Columns { get; set; } = new List<string>
|
||||
{
|
||||
"Date", "TemperatureC", "TemperatureF", "Summary",
|
||||
"Date", "TemperatureC", "TemperatureF", "Summary",
|
||||
"Date", "TemperatureC", "TemperatureF", "Summary",
|
||||
"Date", "TemperatureC", "TemperatureF", "Summary",
|
||||
"Date", "TemperatureC", "TemperatureF", "Summary",
|
||||
};
|
||||
|
||||
private static string[] sampleSummaries = new[] { "Balmy", "Chilly", "Freezing", "Bracing" };
|
||||
private static WeatherForecast[] staticSampleDataPage1 = Enumerable.Range(0, 200).Select(CreateSampleDataItem).ToArray();
|
||||
private static WeatherForecast[] staticSampleDataPage2 = Enumerable.Range(200, 200).Select(CreateSampleDataItem).ToArray();
|
||||
|
||||
private static WeatherForecast CreateSampleDataItem(int index) => new WeatherForecast
|
||||
{
|
||||
Date = DateTime.Now.Date.AddDays(index),
|
||||
Summary = sampleSummaries[index % sampleSummaries.Length],
|
||||
TemperatureC = index,
|
||||
};
|
||||
|
||||
void Show()
|
||||
{
|
||||
forecasts = staticSampleDataPage1;
|
||||
}
|
||||
|
||||
void Hide()
|
||||
{
|
||||
forecasts = null;
|
||||
}
|
||||
|
||||
void ChangePage()
|
||||
{
|
||||
forecasts = (forecasts == staticSampleDataPage1) ? staticSampleDataPage2 : staticSampleDataPage1;
|
||||
}
|
||||
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
BenchmarkEvent.Send(JSRuntime, "Finished rendering table");
|
||||
}
|
||||
|
||||
public class WeatherForecast
|
||||
{
|
||||
public DateTime Date { get; set; }
|
||||
|
||||
public int TemperatureC { get; set; }
|
||||
|
||||
public string Summary { get; set; }
|
||||
|
||||
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
@using WeatherForecast = Pages.GridRendering.WeatherForecast
|
||||
|
||||
<td @attributes="@Attributes"
|
||||
@onclick="@(() => OnClick.Invoke(CellIndex))"
|
||||
>
|
||||
@switch (Field)
|
||||
{
|
||||
case "Date":
|
||||
@Item.Date.ToShortDateString()
|
||||
break;
|
||||
case "TemperatureC":
|
||||
@Item.TemperatureC
|
||||
break;
|
||||
case "TemperatureF":
|
||||
@Item.TemperatureF
|
||||
break;
|
||||
case "Summary":
|
||||
@Item.Summary
|
||||
break;
|
||||
}
|
||||
</td>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public WeatherForecast Item { get; set; }
|
||||
|
||||
[CascadingParameter]
|
||||
public TableComponent ParentTable { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string Field { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public int CellIndex { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public int RowIndex { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool Selected { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string FormatString { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public Func<int, Task> OnClick { get; set; }
|
||||
|
||||
private protected Dictionary<string, object> Attributes
|
||||
{
|
||||
get
|
||||
{
|
||||
var attributes = new Dictionary<string, object>();
|
||||
|
||||
attributes["tabindex"] = CellIndex;
|
||||
|
||||
return attributes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
@using WeatherForecast = Pages.GridRendering.WeatherForecast
|
||||
|
||||
<tr class="complex-table-row" style="@rowStyle">
|
||||
@foreach (var item in Columns)
|
||||
{
|
||||
<Cell Item="@Item"
|
||||
Field="@item"
|
||||
CellIndex="1"
|
||||
RowIndex="2"
|
||||
Selected="@isSelected"
|
||||
FormatString="foo"
|
||||
OnClick="@OnCellClick">
|
||||
</Cell>
|
||||
}
|
||||
</tr>
|
||||
|
||||
|
||||
@code {
|
||||
|
||||
private bool isSelected = false;
|
||||
|
||||
private string rowStyle => isSelected ? "background-color: lightblue;" : "";
|
||||
|
||||
[Parameter]
|
||||
public WeatherForecast Item { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public List<string> Columns { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public Func<int, Task> OnClick { get; set; }
|
||||
|
||||
Task OnCellClick(int args)
|
||||
{
|
||||
isSelected = !isSelected;
|
||||
|
||||
return OnClick.Invoke(args);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
@using WeatherForecast = Pages.GridRendering.WeatherForecast
|
||||
|
||||
@foreach (var item in Data)
|
||||
{
|
||||
<Row Item="@item" Columns="@Columns"
|
||||
OnClick="@OnClick"></Row>
|
||||
}
|
||||
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public WeatherForecast[] Data { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public List<string> Columns { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public Func<int, Task> OnClick { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
@using WeatherForecast = Pages.GridRendering.WeatherForecast
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
@foreach (var item in Columns)
|
||||
{
|
||||
<th>@item</th>
|
||||
}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<CascadingValue Value="@this">
|
||||
<RowCollection Data="@Data"
|
||||
Columns="@Columns"
|
||||
OnClick="@RefreshComponent"></RowCollection>
|
||||
</CascadingValue>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public WeatherForecast[] Data { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public List<string> Columns { get; set; }
|
||||
|
||||
DateTime t1;
|
||||
DateTime t2;
|
||||
Task RefreshComponent(int index)
|
||||
{
|
||||
t1 = DateTime.Now;
|
||||
StateHasChanged();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
protected override Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (!firstRender)
|
||||
{
|
||||
t2 = DateTime.Now;
|
||||
Console.WriteLine("Refresh Time " + (t2 - t1).TotalMilliseconds);
|
||||
}
|
||||
return base.OnAfterRenderAsync(firstRender);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
@typeparam TRowData
|
||||
|
||||
<CascadingValue IsFixed="true" Value="this">@ChildContent</CascadingValue>
|
||||
|
||||
<table @attributes="@Attributes">
|
||||
<thead>
|
||||
<tr>
|
||||
@foreach (var col in columns)
|
||||
{
|
||||
col.RenderHeader(__builder);
|
||||
}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in Data)
|
||||
{
|
||||
<tr @key="item.GetHashCode()" class="@(RowClass?.Invoke(item))">
|
||||
@foreach (var col in columns)
|
||||
{
|
||||
col.RenderCell(__builder, item);
|
||||
}
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@code {
|
||||
[Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object> Attributes { get; set; }
|
||||
[Parameter] public ICollection<TRowData> Data { get; set; }
|
||||
[Parameter] public RenderFragment ChildContent { get; set; }
|
||||
[Parameter] public Func<TRowData, string> RowClass { get; set; }
|
||||
|
||||
private List<GridColumn<TRowData>> columns = new List<GridColumn<TRowData>>();
|
||||
|
||||
internal void AddColumn(GridColumn<TRowData> column)
|
||||
{
|
||||
columns.Add(column);
|
||||
}
|
||||
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
// On the first render, we collect the list of columns, then we have to render them.
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
@typeparam TRowData
|
||||
@using Microsoft.AspNetCore.Components.Rendering
|
||||
@code {
|
||||
[CascadingParameter] public Grid<TRowData> OwnerGrid { get; set; }
|
||||
[Parameter] public string Title { get; set; }
|
||||
[Parameter] public TRowData RowData { get; set; }
|
||||
[Parameter] public RenderFragment<TRowData> ChildContent { get; set; }
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
OwnerGrid.AddColumn(this);
|
||||
}
|
||||
|
||||
internal void RenderHeader(RenderTreeBuilder __builder)
|
||||
{
|
||||
<th>@Title</th>
|
||||
}
|
||||
|
||||
internal void RenderCell(RenderTreeBuilder __builder, TRowData rowData)
|
||||
{
|
||||
<td>@ChildContent(rowData)</td>
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,8 @@
|
|||
<a href="renderlist">RenderList</a> |
|
||||
<a href="json">JSON</a> |
|
||||
<a href="orgchart">OrgChart</a> |
|
||||
<a href="timer">Timer</a>
|
||||
<a href="timer">Timer</a> |
|
||||
<a href="gridrendering">Grid</a>
|
||||
|
||||
<hr />
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
@using WeatherForecast = Pages.GridRendering.WeatherForecast
|
||||
|
||||
<td @onclick="@(() => OnClick.Invoke(1))">
|
||||
@switch (Field)
|
||||
{
|
||||
case "Date":
|
||||
@Item.Date.ToShortDateString()
|
||||
break;
|
||||
case "TemperatureC":
|
||||
@Item.TemperatureC
|
||||
break;
|
||||
case "TemperatureF":
|
||||
@Item.TemperatureF
|
||||
break;
|
||||
case "Summary":
|
||||
@Item.Summary
|
||||
break;
|
||||
}
|
||||
</td>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public WeatherForecast Item { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string Field { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public Func<int, Task> OnClick { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
@using WeatherForecast = Pages.GridRendering.WeatherForecast
|
||||
|
||||
<tr style="@rowStyle">
|
||||
@foreach (var item in Columns)
|
||||
{
|
||||
<Cell Item="@Item"
|
||||
Field="@item"
|
||||
OnClick="@OnCellClick">
|
||||
</Cell>
|
||||
}
|
||||
</tr>
|
||||
|
||||
|
||||
@code {
|
||||
|
||||
private bool isSelected = false;
|
||||
|
||||
private string rowStyle => isSelected ? "background-color: lightblue;" : "";
|
||||
|
||||
[Parameter]
|
||||
public WeatherForecast Item { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public List<string> Columns { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public Func<int, Task> OnClick { get; set; }
|
||||
|
||||
Task OnCellClick(int args)
|
||||
{
|
||||
isSelected = !isSelected;
|
||||
|
||||
return OnClick.Invoke(args);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
@using WeatherForecast = Pages.GridRendering.WeatherForecast
|
||||
|
||||
@foreach (var item in Data)
|
||||
{
|
||||
<Row Item="@item" Columns="@Columns"
|
||||
OnClick="@OnClick"></Row>
|
||||
}
|
||||
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public WeatherForecast[] Data { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public List<string> Columns { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public Func<int, Task> OnClick { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
@using WeatherForecast = Pages.GridRendering.WeatherForecast
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
@foreach (var item in Columns)
|
||||
{
|
||||
<th>@item</th>
|
||||
}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<RowCollection Data="@Data"
|
||||
Columns="@Columns"
|
||||
OnClick="@RefreshComponent"></RowCollection>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public WeatherForecast[] Data { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public List<string> Columns { get; set; }
|
||||
|
||||
DateTime t1;
|
||||
DateTime t2;
|
||||
Task RefreshComponent(int index)
|
||||
{
|
||||
t1 = DateTime.Now;
|
||||
StateHasChanged();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
protected override Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (!firstRender)
|
||||
{
|
||||
t2 = DateTime.Now;
|
||||
Console.WriteLine("Refresh Time " + (t2 - t1).TotalMilliseconds);
|
||||
}
|
||||
return base.OnAfterRenderAsync(firstRender);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
import { group, benchmark, setup, teardown } from './lib/minibench/minibench.js';
|
||||
import { receiveEvent } from './util/BenchmarkEvents.js';
|
||||
import { BlazorApp } from './util/BlazorApp.js';
|
||||
import { setInputValue } from './util/DOM.js';
|
||||
|
||||
group('Grid', () => {
|
||||
let app;
|
||||
|
||||
setup(async () => {
|
||||
app = new BlazorApp();
|
||||
await app.start();
|
||||
app.navigateTo('gridrendering');
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
app.dispose();
|
||||
});
|
||||
|
||||
benchmark('PlainTable: From blank', () => measureRenderGridFromBlank(app), {
|
||||
setup: () => prepare(app, 'PlainTable', false),
|
||||
descriptor: {
|
||||
name: 'blazorwasm/render-plaintable-from-blank',
|
||||
description: 'Time to render plain table from blank (ms)'
|
||||
}
|
||||
});
|
||||
|
||||
benchmark('PlainTable: Switch pages', () => measureRenderGridSwitchPages(app), {
|
||||
setup: () => prepare(app, 'PlainTable', true),
|
||||
descriptor: {
|
||||
name: 'blazorwasm/render-plaintable-switch-pages',
|
||||
description: 'Time to render plain table change of page (ms)'
|
||||
}
|
||||
});
|
||||
|
||||
benchmark('ComplexTable: From blank', () => measureRenderGridFromBlank(app), {
|
||||
setup: () => prepare(app, 'ComplexTable', false),
|
||||
descriptor: {
|
||||
name: 'blazorwasm/render-complextable-from-blank',
|
||||
description: 'Time to render complex table from blank (ms)'
|
||||
}
|
||||
});
|
||||
|
||||
benchmark('ComplexTable: Switch pages', () => measureRenderGridSwitchPages(app), {
|
||||
setup: () => prepare(app, 'ComplexTable', true),
|
||||
descriptor: {
|
||||
name: 'blazorwasm/render-complextable-switch-pages',
|
||||
description: 'Time to render complex table change of page (ms)'
|
||||
}
|
||||
});
|
||||
|
||||
benchmark('FastGrid: From blank', () => measureRenderGridFromBlank(app), {
|
||||
setup: () => prepare(app, 'FastGrid', false),
|
||||
descriptor: {
|
||||
name: 'blazorwasm/render-fastgrid-from-blank',
|
||||
description: 'Time to render fast grid from blank (ms)'
|
||||
}
|
||||
});
|
||||
|
||||
benchmark('FastGrid: Switch pages', () => measureRenderGridSwitchPages(app), {
|
||||
setup: () => prepare(app, 'FastGrid', true),
|
||||
descriptor: {
|
||||
name: 'blazorwasm/render-fastgrid-switch-pages',
|
||||
description: 'Time to render fast grid change of page (ms)'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
async function prepare(app, renderMode, populateTable) {
|
||||
const renderModeSelect = app.window.document.querySelector('#render-mode');
|
||||
setInputValue(renderModeSelect, renderMode);
|
||||
|
||||
if (populateTable) {
|
||||
let nextRenderCompletion = receiveEvent('Finished rendering table');
|
||||
app.window.document.querySelector(populateTable ? '#show' : '#hide').click();
|
||||
await nextRenderCompletion;
|
||||
}
|
||||
}
|
||||
|
||||
async function measureRenderGridFromBlank(app) {
|
||||
const appDocument = app.window.document;
|
||||
|
||||
let nextRenderCompletion = receiveEvent('Finished rendering table');
|
||||
appDocument.querySelector('#hide').click();
|
||||
await nextRenderCompletion;
|
||||
|
||||
if (appDocument.querySelectorAll('tbody tr').length !== 0) {
|
||||
throw new Error('Wrong number of rows rendered');
|
||||
}
|
||||
|
||||
nextRenderCompletion = receiveEvent('Finished rendering table');
|
||||
appDocument.querySelector('#show').click();
|
||||
await nextRenderCompletion;
|
||||
|
||||
if (appDocument.querySelectorAll('tbody tr').length !== 200) {
|
||||
throw new Error('Wrong number of rows rendered');
|
||||
}
|
||||
}
|
||||
|
||||
async function measureRenderGridSwitchPages(app) {
|
||||
const appDocument = app.window.document;
|
||||
|
||||
let nextRenderCompletion = receiveEvent('Finished rendering table');
|
||||
appDocument.querySelector('#change-page').click();
|
||||
await nextRenderCompletion;
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import './appStartup.js';
|
|||
import './renderList.js';
|
||||
import './jsonHandling.js';
|
||||
import './orgChart.js';
|
||||
import './grid.js';
|
||||
import { getBlazorDownloadSize } from './blazorDownloadSize.js';
|
||||
|
||||
new HtmlUI('E2E Performance', '#display');
|
||||
|
|
|
|||
|
|
@ -20,10 +20,11 @@ ADD https://api.github.com/repos/dotnet/aspnetcore/git/ref/heads/${gitBranch} /a
|
|||
RUN git init \
|
||||
&& git fetch https://github.com/aspnet/aspnetcore ${gitBranch} \
|
||||
&& git reset --hard FETCH_HEAD \
|
||||
&& git submodule update --init
|
||||
&& git submodule update --init \
|
||||
&& git remote add origin https://github.com/aspnet/aspnetcore
|
||||
|
||||
RUN ./restore.sh
|
||||
RUN .dotnet/dotnet publish -c Release -r linux-x64 -o /app ./src/Components/benchmarkapps/Wasm.Performance/Driver/Wasm.Performance.Driver.csproj
|
||||
RUN .dotnet/dotnet publish -c Release --no-restore -o /app ./src/Components/benchmarkapps/Wasm.Performance/Driver/Wasm.Performance.Driver.csproj
|
||||
RUN chmod +x /app/Wasm.Performance.Driver
|
||||
|
||||
WORKDIR /app
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ FROM selenium/standalone-chrome:3.141.59-mercury as final
|
|||
ENV StressRunDuration=0
|
||||
|
||||
WORKDIR /app
|
||||
COPY ./Driver/bin/Release/netcoreapp3.1/linux-x64/publish ./
|
||||
COPY ./Driver/bin/Release/net5.0/linux-x64/publish ./
|
||||
COPY ./exec.sh ./
|
||||
|
||||
ENTRYPOINT [ "bash", "./exec.sh" ]
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using BasicTestApp;
|
|||
using BasicTestApp.HttpClientTest;
|
||||
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures;
|
||||
using Microsoft.AspNetCore.E2ETesting;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using OpenQA.Selenium;
|
||||
using OpenQA.Selenium.Support.UI;
|
||||
using TestServer;
|
||||
|
|
@ -44,6 +45,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23366")]
|
||||
public void CanSendAndReceiveBytes()
|
||||
{
|
||||
IssueRequest("/subdir/api/data");
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using BasicTestApp;
|
|||
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure;
|
||||
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures;
|
||||
using Microsoft.AspNetCore.E2ETesting;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Moq;
|
||||
using OpenQA.Selenium;
|
||||
using OpenQA.Selenium.Support.UI;
|
||||
|
|
@ -506,6 +507,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23596")]
|
||||
public void CanBindTextboxNullableDouble()
|
||||
{
|
||||
var target = Browser.FindElement(By.Id("textbox-nullable-double"));
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
[QuarantinedTest]
|
||||
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23366")]
|
||||
public void CanRenderTextOnlyComponent()
|
||||
{
|
||||
var appElement = Browser.MountTestComponent<TextOnlyComponent>();
|
||||
|
|
@ -400,6 +400,26 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
|||
Browser.Equal("Clicks: 2", () => inputElement.GetAttribute("value"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanUseFocusExtensionToFocusElement()
|
||||
{
|
||||
var appElement = Browser.MountTestComponent<ElementFocusComponent>();
|
||||
var buttonElement = appElement.FindElement(By.Id("focus-button"));
|
||||
|
||||
// Make sure the input element isn't focused when the test begins; we don't want
|
||||
// the test to pass just because the input started as the focused element
|
||||
Browser.NotEqual("focus-input", getFocusedElementId);
|
||||
|
||||
// Click the button whose callback focuses the input element
|
||||
buttonElement.Click();
|
||||
|
||||
// Verify that the input element is focused
|
||||
Browser.Equal("focus-input", getFocusedElementId);
|
||||
|
||||
// A local helper that gets the ID of the focused element.
|
||||
string getFocusedElementId() => Browser.SwitchTo().ActiveElement().GetAttribute("id");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanCaptureReferencesToDynamicallyAddedElements()
|
||||
{
|
||||
|
|
@ -464,6 +484,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
[QuarantinedTest]
|
||||
public void CanRenderMarkupBlocks()
|
||||
{
|
||||
var appElement = Browser.MountTestComponent<MarkupBlockComponent>();
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using BasicTestApp;
|
|||
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure;
|
||||
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures;
|
||||
using Microsoft.AspNetCore.E2ETesting;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using OpenQA.Selenium;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
|
@ -50,6 +51,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23596")]
|
||||
public void ShowsErrorNotification_OnError_Reload()
|
||||
{
|
||||
var causeErrorButton = Browser.Exists(By.Id("throw-simple-exception"));
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue