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
|
jobName: Linux_musl_x64_build
|
||||||
jobDisplayName: "Build: Linux Musl x64"
|
jobDisplayName: "Build: Linux Musl x64"
|
||||||
agentOs: Linux
|
agentOs: Linux
|
||||||
buildScript: ./dockerbuild.sh alpine
|
container: mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.9-WithNode-0fc54a3-20190918214015
|
||||||
|
buildScript: ./build.sh
|
||||||
buildArgs:
|
buildArgs:
|
||||||
--arch x64
|
--arch x64
|
||||||
--os-name linux-musl
|
--os-name linux-musl
|
||||||
|
|
@ -448,6 +449,7 @@ stages:
|
||||||
$(_InternalRuntimeDownloadArgs)
|
$(_InternalRuntimeDownloadArgs)
|
||||||
installNodeJs: false
|
installNodeJs: false
|
||||||
installJdk: false
|
installJdk: false
|
||||||
|
skipComponentGovernanceDetection: true
|
||||||
artifacts:
|
artifacts:
|
||||||
- name: Linux_musl_x64_Logs
|
- name: Linux_musl_x64_Logs
|
||||||
path: artifacts/log/
|
path: artifacts/log/
|
||||||
|
|
@ -466,7 +468,8 @@ stages:
|
||||||
jobDisplayName: "Build: Linux Musl ARM64"
|
jobDisplayName: "Build: Linux Musl ARM64"
|
||||||
agentOs: Linux
|
agentOs: Linux
|
||||||
useHostedUbuntu: false
|
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:
|
buildArgs:
|
||||||
--arch arm64
|
--arch arm64
|
||||||
--os-name linux-musl
|
--os-name linux-musl
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,8 @@
|
||||||
# Specifies what directory to run build.sh/cmd
|
# Specifies what directory to run build.sh/cmd
|
||||||
# buildScript: string
|
# buildScript: string
|
||||||
# Specifies the build script to run. Defaults to build.sh or build.cmd.
|
# 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
|
# See https://docs.microsoft.com/en-us/vsts/pipelines/yaml-schema for details
|
||||||
#
|
#
|
||||||
|
|
@ -60,6 +61,7 @@ parameters:
|
||||||
installJdk: true
|
installJdk: true
|
||||||
timeoutInMinutes: 180
|
timeoutInMinutes: 180
|
||||||
useHostedUbuntu: true
|
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).
|
# 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
|
# 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
|
name: NetCoreInternal-Pool
|
||||||
# Visual Studio Enterprise - contains some stuff, like SQL Server and IIS Express, that we use for testing
|
# Visual Studio Enterprise - contains some stuff, like SQL Server and IIS Express, that we use for testing
|
||||||
queue: BuildPool.Server.Amd64.VS2019
|
queue: BuildPool.Server.Amd64.VS2019
|
||||||
|
${{ if ne(parameters.container, '') }}:
|
||||||
|
container: ${{ parameters.container }}
|
||||||
variables:
|
variables:
|
||||||
- AgentOsName: ${{ parameters.agentOs }}
|
- AgentOsName: ${{ parameters.agentOs }}
|
||||||
- ASPNETCORE_TEST_LOG_MAXPATH: "200" # Keep test log file name length low enough for artifact zipping
|
- ASPNETCORE_TEST_LOG_MAXPATH: "200" # Keep test log file name length low enough for artifact zipping
|
||||||
|
|
@ -238,7 +242,7 @@ jobs:
|
||||||
continueOnError: true
|
continueOnError: true
|
||||||
condition: always()
|
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
|
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
|
||||||
condition: and(succeeded(), ne(variables['CG_RAN'], 'true'))
|
condition: and(succeeded(), ne(variables['CG_RAN'], 'true'))
|
||||||
displayName: 'Component Detection'
|
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
|
# We only want to run quarantined tests on master
|
||||||
trigger:
|
pr: none
|
||||||
batch: true
|
trigger: none
|
||||||
branches:
|
|
||||||
include:
|
|
||||||
- master
|
|
||||||
|
|
||||||
schedules:
|
schedules:
|
||||||
- cron: "0 */4 * * *"
|
- cron: "0 18 * * *"
|
||||||
displayName: Every 4 hours test run
|
displayName: Run tests once a day at 11 PM
|
||||||
branches:
|
branches:
|
||||||
include:
|
include:
|
||||||
- master
|
- master
|
||||||
|
|
@ -28,7 +25,7 @@ jobs:
|
||||||
jobName: Helix_quarantined_x64
|
jobName: Helix_quarantined_x64
|
||||||
jobDisplayName: 'Tests: Helix'
|
jobDisplayName: 'Tests: Helix'
|
||||||
agentOs: Windows
|
agentOs: Windows
|
||||||
timeoutInMinutes: 180
|
timeoutInMinutes: 480
|
||||||
steps:
|
steps:
|
||||||
# Build the shared framework
|
# Build the shared framework
|
||||||
- script: ./build.cmd -ci -nobl -all -pack -arch x64 /p:ASPNETCORE_TEST_LOG_DIR=artifacts/log
|
- 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
|
- script: ./build.cmd -ci -nobl -noBuildRepoTasks -restore -noBuild -noBuildNative -projects src/Grpc/**/*.csproj
|
||||||
displayName: Restore interop projects
|
displayName: Restore interop projects
|
||||||
- script: ./build.cmd -ci -nobl -noBuildRepoTasks -noRestore -test -all -noBuildJava -noBuildNative
|
- 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
|
/p:BuildInteropProjects=true /p:RunTemplateTests=true /p:ASPNETCORE_TEST_LOG_DIR=artifacts/log
|
||||||
displayName: Run build.cmd helix target
|
displayName: Run build.cmd helix target
|
||||||
continueOnError: true
|
continueOnError: true
|
||||||
|
|
@ -48,102 +45,27 @@ jobs:
|
||||||
path: artifacts/log/
|
path: artifacts/log/
|
||||||
publishOnError: true
|
publishOnError: true
|
||||||
|
|
||||||
|
# Helix ARM64
|
||||||
- template: jobs/default-build.yml
|
- template: jobs/default-build.yml
|
||||||
parameters:
|
parameters:
|
||||||
jobName: Windows_Quarantined_x64
|
jobName: Helix_quarantined_arm64
|
||||||
jobDisplayName: 'Tests: Windows x64'
|
jobDisplayName: "Tests: Helix ARM64"
|
||||||
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"
|
|
||||||
agentOs: Linux
|
agentOs: Linux
|
||||||
timeoutInMinutes: 180
|
timeoutInMinutes: 480
|
||||||
isTestingJob: true
|
|
||||||
useHostedUbuntu: false
|
|
||||||
steps:
|
steps:
|
||||||
- bash: ./build.sh --all --pack --ci --nobl --no-build-java
|
- script: ./restore.sh -ci -nobl
|
||||||
displayName: Build
|
displayName: Restore
|
||||||
# The templates part can be removed when the Blazor Templates run on Helix
|
- script: ./build.sh --ci --nobl --noBuildRepoTasks --arch arm64 -test --no-build-nodejs --all --projects
|
||||||
- bash: ./src/ProjectTemplates/build.sh --ci --nobl --pack --no-restore --no-build-deps
|
$(Build.SourcesDirectory)/eng/helix/helix.proj /p:IsHelixJob=true /p:IsHelixDaily=true /p:RunQuarantinedTests=true
|
||||||
displayName: Pack Templates (for Template tests)
|
/p:ASPNETCORE_TEST_LOG_DIR=artifacts/log
|
||||||
- bash: ./build.sh --no-build --ci --nobl --test -p:RunTemplateTests=true -p:RunQuarantinedTests=true -p:SkipHelixReadyTests=true
|
displayName: Run build.sh helix arm64 target
|
||||||
displayName: Run Quarantined Tests
|
|
||||||
continueOnError: true
|
continueOnError: true
|
||||||
- task: PublishTestResults@2
|
env:
|
||||||
displayName: Publish Quarantined Test Results
|
HelixApiAccessToken: $(HelixApiAccessToken) # Needed for internal queues
|
||||||
inputs:
|
SYSTEM_ACCESSTOKEN: $(System.AccessToken) # We need to set this env var to publish helix results to Azure Dev Ops
|
||||||
testResultsFormat: 'xUnit'
|
installNodeJs: false
|
||||||
testResultsFiles: '*.xml'
|
|
||||||
searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)/Quarantined'
|
|
||||||
condition: always()
|
|
||||||
artifacts:
|
artifacts:
|
||||||
- name: Linux_Quarantined_Test_Logs
|
- name: Helix_arm64_logs
|
||||||
path: artifacts/log/
|
path: artifacts/log/
|
||||||
publishOnError: true
|
publishOnError: true
|
||||||
includeForks: 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/common/ @dotnet-maestro-bot
|
||||||
/eng/Versions.props @dotnet-maestro-bot @dougbu
|
/eng/Versions.props @dotnet-maestro-bot @dougbu
|
||||||
/eng/Version.Details.xml @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/DefaultBuilder/ @tratcher
|
||||||
/src/Hosting/ @tratcher
|
/src/Hosting/ @tratcher
|
||||||
/src/Http/ @tratcher @jkotalik
|
/src/Http/ @tratcher @jkotalik
|
||||||
/src/Middleware/ @tratcher
|
/src/Middleware/ @tratcher
|
||||||
/src/Middleware/HttpsPolicy/ @jkotalik
|
/src/Middleware/HttpsPolicy/ @jkotalik
|
||||||
/src/Middleware/Rewrite/ @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/Security/ @tratcher
|
||||||
/src/Servers/ @tratcher @jkotalik @halter73
|
/src/Servers/ @tratcher @jkotalik @halter73
|
||||||
/src/Shared/runtime/ @dotnet/http
|
/src/Shared/runtime/ @dotnet/http
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,8 @@ To update an existing copy, run:
|
||||||
git submodule update --init --recursive
|
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
|
## Building in Visual Studio
|
||||||
|
|
||||||
Before opening our .sln files in Visual Studio or VS Code, you need to perform the following actions.
|
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.
|
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.
|
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.
|
* Run the installers produced in `artifacts/installers/{Debug, Release}/` for your platform.
|
||||||
* Add a NuGet.Config to your project directory with the following content:
|
* 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
|
- 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)
|
- 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?
|
## 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.
|
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>.
|
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.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.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="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.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.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" />
|
<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>
|
<Uri>https://github.com/dotnet/blazor</Uri>
|
||||||
<Sha>cc449601d638ffaab58ae9487f0fd010bb178a12</Sha>
|
<Sha>cc449601d638ffaab58ae9487f0fd010bb178a12</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/efcore</Uri>
|
||||||
<Sha>0f2b5023539eb0c5a4fc565af7e59b95c252529f</Sha>
|
<Sha>dff6a1abc282bb642042b4fe3a643f5b586bcf03</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/efcore</Uri>
|
||||||
<Sha>0f2b5023539eb0c5a4fc565af7e59b95c252529f</Sha>
|
<Sha>dff6a1abc282bb642042b4fe3a643f5b586bcf03</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/efcore</Uri>
|
||||||
<Sha>0f2b5023539eb0c5a4fc565af7e59b95c252529f</Sha>
|
<Sha>dff6a1abc282bb642042b4fe3a643f5b586bcf03</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/efcore</Uri>
|
||||||
<Sha>0f2b5023539eb0c5a4fc565af7e59b95c252529f</Sha>
|
<Sha>dff6a1abc282bb642042b4fe3a643f5b586bcf03</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/efcore</Uri>
|
||||||
<Sha>0f2b5023539eb0c5a4fc565af7e59b95c252529f</Sha>
|
<Sha>dff6a1abc282bb642042b4fe3a643f5b586bcf03</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/efcore</Uri>
|
||||||
<Sha>0f2b5023539eb0c5a4fc565af7e59b95c252529f</Sha>
|
<Sha>dff6a1abc282bb642042b4fe3a643f5b586bcf03</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/efcore</Uri>
|
||||||
<Sha>0f2b5023539eb0c5a4fc565af7e59b95c252529f</Sha>
|
<Sha>dff6a1abc282bb642042b4fe3a643f5b586bcf03</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<!--
|
<!--
|
||||||
Win-x64 is used here because we have picked an arbitrary runtime identifier to flow the version of the latest NETCore.App runtime.
|
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.
|
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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
</ProductDependencies>
|
</ProductDependencies>
|
||||||
<ToolsetDependencies>
|
<ToolsetDependencies>
|
||||||
<!-- Listed explicitly to workaround https://github.com/dotnet/cli/issues/10528 -->
|
<!-- 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>
|
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||||
<Sha>b0f97149538e3dabde2267efa326c76a628a30ff</Sha>
|
<Sha>d3e6947f39ee04b0a6a44bfe6ba1310fbc10c7e5</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.DotNet.GenAPI" Version="5.0.0-beta.20316.1">
|
<Dependency Name="Microsoft.DotNet.GenAPI" Version="5.0.0-beta.20316.1">
|
||||||
<Uri>https://github.com/dotnet/arcade</Uri>
|
<Uri>https://github.com/dotnet/arcade</Uri>
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
<AspNetCoreMajorVersion>5</AspNetCoreMajorVersion>
|
<AspNetCoreMajorVersion>5</AspNetCoreMajorVersion>
|
||||||
<AspNetCoreMinorVersion>0</AspNetCoreMinorVersion>
|
<AspNetCoreMinorVersion>0</AspNetCoreMinorVersion>
|
||||||
<AspNetCorePatchVersion>0</AspNetCorePatchVersion>
|
<AspNetCorePatchVersion>0</AspNetCorePatchVersion>
|
||||||
<PreReleaseVersionIteration>7</PreReleaseVersionIteration>
|
<PreReleaseVersionIteration>8</PreReleaseVersionIteration>
|
||||||
<!--
|
<!--
|
||||||
When StabilizePackageVersion is set to 'true', this branch will produce stable outputs for 'Shipping' packages
|
When StabilizePackageVersion is set to 'true', this branch will produce stable outputs for 'Shipping' packages
|
||||||
-->
|
-->
|
||||||
|
|
@ -66,79 +66,79 @@
|
||||||
<!-- Packages from dotnet/roslyn -->
|
<!-- Packages from dotnet/roslyn -->
|
||||||
<MicrosoftNetCompilersToolsetPackageVersion>3.7.0-4.20319.6</MicrosoftNetCompilersToolsetPackageVersion>
|
<MicrosoftNetCompilersToolsetPackageVersion>3.7.0-4.20319.6</MicrosoftNetCompilersToolsetPackageVersion>
|
||||||
<!-- Packages from dotnet/runtime -->
|
<!-- Packages from dotnet/runtime -->
|
||||||
<MicrosoftExtensionsDependencyModelPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsDependencyModelPackageVersion>
|
<MicrosoftExtensionsDependencyModelPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsDependencyModelPackageVersion>
|
||||||
<MicrosoftNETCoreAppInternalPackageVersion>5.0.0-preview.7.20326.1</MicrosoftNETCoreAppInternalPackageVersion>
|
<MicrosoftNETCoreAppInternalPackageVersion>5.0.0-preview.8.20352.6</MicrosoftNETCoreAppInternalPackageVersion>
|
||||||
<MicrosoftNETCoreAppRefPackageVersion>5.0.0-preview.7.20326.1</MicrosoftNETCoreAppRefPackageVersion>
|
<MicrosoftNETCoreAppRefPackageVersion>5.0.0-preview.8.20352.6</MicrosoftNETCoreAppRefPackageVersion>
|
||||||
<MicrosoftNETCoreAppRuntimewinx64PackageVersion>5.0.0-preview.7.20326.1</MicrosoftNETCoreAppRuntimewinx64PackageVersion>
|
<MicrosoftNETCoreAppRuntimewinx64PackageVersion>5.0.0-preview.8.20352.6</MicrosoftNETCoreAppRuntimewinx64PackageVersion>
|
||||||
<MicrosoftWin32RegistryPackageVersion>5.0.0-preview.7.20326.1</MicrosoftWin32RegistryPackageVersion>
|
<MicrosoftWin32RegistryPackageVersion>5.0.0-preview.8.20352.6</MicrosoftWin32RegistryPackageVersion>
|
||||||
<MicrosoftWin32SystemEventsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftWin32SystemEventsPackageVersion>
|
<MicrosoftWin32SystemEventsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftWin32SystemEventsPackageVersion>
|
||||||
<MicrosoftExtensionsCachingAbstractionsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsCachingAbstractionsPackageVersion>
|
<MicrosoftExtensionsCachingAbstractionsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsCachingAbstractionsPackageVersion>
|
||||||
<MicrosoftExtensionsCachingMemoryPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsCachingMemoryPackageVersion>
|
<MicrosoftExtensionsCachingMemoryPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsCachingMemoryPackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationAbstractionsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsConfigurationAbstractionsPackageVersion>
|
<MicrosoftExtensionsConfigurationAbstractionsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsConfigurationAbstractionsPackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationBinderPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsConfigurationBinderPackageVersion>
|
<MicrosoftExtensionsConfigurationBinderPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsConfigurationBinderPackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationCommandLinePackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsConfigurationCommandLinePackageVersion>
|
<MicrosoftExtensionsConfigurationCommandLinePackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsConfigurationCommandLinePackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>
|
<MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>
|
<MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationIniPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsConfigurationIniPackageVersion>
|
<MicrosoftExtensionsConfigurationIniPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsConfigurationIniPackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationJsonPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsConfigurationJsonPackageVersion>
|
<MicrosoftExtensionsConfigurationJsonPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsConfigurationJsonPackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsConfigurationPackageVersion>
|
<MicrosoftExtensionsConfigurationPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsConfigurationPackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationUserSecretsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsConfigurationUserSecretsPackageVersion>
|
<MicrosoftExtensionsConfigurationUserSecretsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsConfigurationUserSecretsPackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationXmlPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsConfigurationXmlPackageVersion>
|
<MicrosoftExtensionsConfigurationXmlPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsConfigurationXmlPackageVersion>
|
||||||
<MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>
|
<MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>
|
||||||
<MicrosoftExtensionsDependencyInjectionPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsDependencyInjectionPackageVersion>
|
<MicrosoftExtensionsDependencyInjectionPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsDependencyInjectionPackageVersion>
|
||||||
<MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>
|
<MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>
|
||||||
<MicrosoftExtensionsFileProvidersCompositePackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsFileProvidersCompositePackageVersion>
|
<MicrosoftExtensionsFileProvidersCompositePackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsFileProvidersCompositePackageVersion>
|
||||||
<MicrosoftExtensionsFileProvidersPhysicalPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsFileProvidersPhysicalPackageVersion>
|
<MicrosoftExtensionsFileProvidersPhysicalPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsFileProvidersPhysicalPackageVersion>
|
||||||
<MicrosoftExtensionsFileSystemGlobbingPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsFileSystemGlobbingPackageVersion>
|
<MicrosoftExtensionsFileSystemGlobbingPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsFileSystemGlobbingPackageVersion>
|
||||||
<MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion>
|
<MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion>
|
||||||
<MicrosoftExtensionsHostingAbstractionsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsHostingAbstractionsPackageVersion>
|
<MicrosoftExtensionsHostingAbstractionsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsHostingAbstractionsPackageVersion>
|
||||||
<MicrosoftExtensionsHostingPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsHostingPackageVersion>
|
<MicrosoftExtensionsHostingPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsHostingPackageVersion>
|
||||||
<MicrosoftExtensionsHttpPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsHttpPackageVersion>
|
<MicrosoftExtensionsHttpPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsHttpPackageVersion>
|
||||||
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
|
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
|
||||||
<MicrosoftExtensionsLoggingConfigurationPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsLoggingConfigurationPackageVersion>
|
<MicrosoftExtensionsLoggingConfigurationPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsLoggingConfigurationPackageVersion>
|
||||||
<MicrosoftExtensionsLoggingConsolePackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsLoggingConsolePackageVersion>
|
<MicrosoftExtensionsLoggingConsolePackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsLoggingConsolePackageVersion>
|
||||||
<MicrosoftExtensionsLoggingDebugPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsLoggingDebugPackageVersion>
|
<MicrosoftExtensionsLoggingDebugPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsLoggingDebugPackageVersion>
|
||||||
<MicrosoftExtensionsLoggingEventSourcePackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsLoggingEventSourcePackageVersion>
|
<MicrosoftExtensionsLoggingEventSourcePackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsLoggingEventSourcePackageVersion>
|
||||||
<MicrosoftExtensionsLoggingEventLogPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsLoggingEventLogPackageVersion>
|
<MicrosoftExtensionsLoggingEventLogPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsLoggingEventLogPackageVersion>
|
||||||
<MicrosoftExtensionsLoggingPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsLoggingPackageVersion>
|
<MicrosoftExtensionsLoggingPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsLoggingPackageVersion>
|
||||||
<MicrosoftExtensionsLoggingTraceSourcePackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsLoggingTraceSourcePackageVersion>
|
<MicrosoftExtensionsLoggingTraceSourcePackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsLoggingTraceSourcePackageVersion>
|
||||||
<MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>
|
<MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>
|
||||||
<MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>
|
<MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>
|
||||||
<MicrosoftExtensionsOptionsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsOptionsPackageVersion>
|
<MicrosoftExtensionsOptionsPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsOptionsPackageVersion>
|
||||||
<MicrosoftExtensionsPrimitivesPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsPrimitivesPackageVersion>
|
<MicrosoftExtensionsPrimitivesPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsPrimitivesPackageVersion>
|
||||||
<MicrosoftExtensionsInternalTransportPackageVersion>5.0.0-preview.7.20326.1</MicrosoftExtensionsInternalTransportPackageVersion>
|
<MicrosoftExtensionsInternalTransportPackageVersion>5.0.0-preview.8.20352.6</MicrosoftExtensionsInternalTransportPackageVersion>
|
||||||
<SystemComponentModelAnnotationsPackageVersion>5.0.0-preview.7.20326.1</SystemComponentModelAnnotationsPackageVersion>
|
<SystemComponentModelAnnotationsPackageVersion>5.0.0-preview.8.20352.6</SystemComponentModelAnnotationsPackageVersion>
|
||||||
<SystemDiagnosticsDiagnosticSourcePackageVersion>5.0.0-preview.7.20326.1</SystemDiagnosticsDiagnosticSourcePackageVersion>
|
<SystemDiagnosticsDiagnosticSourcePackageVersion>5.0.0-preview.8.20352.6</SystemDiagnosticsDiagnosticSourcePackageVersion>
|
||||||
<SystemDiagnosticsEventLogPackageVersion>5.0.0-preview.7.20326.1</SystemDiagnosticsEventLogPackageVersion>
|
<SystemDiagnosticsEventLogPackageVersion>5.0.0-preview.8.20352.6</SystemDiagnosticsEventLogPackageVersion>
|
||||||
<SystemDrawingCommonPackageVersion>5.0.0-preview.7.20326.1</SystemDrawingCommonPackageVersion>
|
<SystemDrawingCommonPackageVersion>5.0.0-preview.8.20352.6</SystemDrawingCommonPackageVersion>
|
||||||
<SystemIOPipelinesPackageVersion>5.0.0-preview.7.20326.1</SystemIOPipelinesPackageVersion>
|
<SystemIOPipelinesPackageVersion>5.0.0-preview.8.20352.6</SystemIOPipelinesPackageVersion>
|
||||||
<SystemNetHttpJsonPackageVersion>5.0.0-preview.7.20326.1</SystemNetHttpJsonPackageVersion>
|
<SystemNetHttpJsonPackageVersion>5.0.0-preview.8.20352.6</SystemNetHttpJsonPackageVersion>
|
||||||
<SystemNetHttpWinHttpHandlerPackageVersion>5.0.0-preview.7.20326.1</SystemNetHttpWinHttpHandlerPackageVersion>
|
<SystemNetHttpWinHttpHandlerPackageVersion>5.0.0-preview.8.20352.6</SystemNetHttpWinHttpHandlerPackageVersion>
|
||||||
<SystemNetWebSocketsWebSocketProtocolPackageVersion>5.0.0-preview.7.20326.1</SystemNetWebSocketsWebSocketProtocolPackageVersion>
|
<SystemNetWebSocketsWebSocketProtocolPackageVersion>5.0.0-preview.8.20352.6</SystemNetWebSocketsWebSocketProtocolPackageVersion>
|
||||||
<SystemReflectionMetadataPackageVersion>5.0.0-preview.7.20326.1</SystemReflectionMetadataPackageVersion>
|
<SystemReflectionMetadataPackageVersion>5.0.0-preview.8.20352.6</SystemReflectionMetadataPackageVersion>
|
||||||
<SystemRuntimeCompilerServicesUnsafePackageVersion>5.0.0-preview.7.20326.1</SystemRuntimeCompilerServicesUnsafePackageVersion>
|
<SystemRuntimeCompilerServicesUnsafePackageVersion>5.0.0-preview.8.20352.6</SystemRuntimeCompilerServicesUnsafePackageVersion>
|
||||||
<SystemSecurityCryptographyCngPackageVersion>5.0.0-preview.7.20326.1</SystemSecurityCryptographyCngPackageVersion>
|
<SystemSecurityCryptographyCngPackageVersion>5.0.0-preview.8.20352.6</SystemSecurityCryptographyCngPackageVersion>
|
||||||
<SystemSecurityCryptographyPkcsPackageVersion>5.0.0-preview.7.20326.1</SystemSecurityCryptographyPkcsPackageVersion>
|
<SystemSecurityCryptographyPkcsPackageVersion>5.0.0-preview.8.20352.6</SystemSecurityCryptographyPkcsPackageVersion>
|
||||||
<SystemSecurityCryptographyXmlPackageVersion>5.0.0-preview.7.20326.1</SystemSecurityCryptographyXmlPackageVersion>
|
<SystemSecurityCryptographyXmlPackageVersion>5.0.0-preview.8.20352.6</SystemSecurityCryptographyXmlPackageVersion>
|
||||||
<SystemSecurityPermissionsPackageVersion>5.0.0-preview.7.20326.1</SystemSecurityPermissionsPackageVersion>
|
<SystemSecurityPermissionsPackageVersion>5.0.0-preview.8.20352.6</SystemSecurityPermissionsPackageVersion>
|
||||||
<SystemSecurityPrincipalWindowsPackageVersion>5.0.0-preview.7.20326.1</SystemSecurityPrincipalWindowsPackageVersion>
|
<SystemSecurityPrincipalWindowsPackageVersion>5.0.0-preview.8.20352.6</SystemSecurityPrincipalWindowsPackageVersion>
|
||||||
<SystemServiceProcessServiceControllerPackageVersion>5.0.0-preview.7.20326.1</SystemServiceProcessServiceControllerPackageVersion>
|
<SystemServiceProcessServiceControllerPackageVersion>5.0.0-preview.8.20352.6</SystemServiceProcessServiceControllerPackageVersion>
|
||||||
<SystemTextEncodingsWebPackageVersion>5.0.0-preview.7.20326.1</SystemTextEncodingsWebPackageVersion>
|
<SystemTextEncodingsWebPackageVersion>5.0.0-preview.8.20352.6</SystemTextEncodingsWebPackageVersion>
|
||||||
<SystemTextJsonPackageVersion>5.0.0-preview.7.20326.1</SystemTextJsonPackageVersion>
|
<SystemTextJsonPackageVersion>5.0.0-preview.8.20352.6</SystemTextJsonPackageVersion>
|
||||||
<SystemThreadingChannelsPackageVersion>5.0.0-preview.7.20326.1</SystemThreadingChannelsPackageVersion>
|
<SystemThreadingChannelsPackageVersion>5.0.0-preview.8.20352.6</SystemThreadingChannelsPackageVersion>
|
||||||
<SystemWindowsExtensionsPackageVersion>5.0.0-preview.7.20326.1</SystemWindowsExtensionsPackageVersion>
|
<SystemWindowsExtensionsPackageVersion>5.0.0-preview.8.20352.6</SystemWindowsExtensionsPackageVersion>
|
||||||
<!-- Only listed explicitly to workaround https://github.com/dotnet/cli/issues/10528 -->
|
<!-- 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 -->
|
<!-- Packages from dotnet/blazor -->
|
||||||
<MicrosoftAspNetCoreComponentsWebAssemblyRuntimePackageVersion>3.2.0</MicrosoftAspNetCoreComponentsWebAssemblyRuntimePackageVersion>
|
<MicrosoftAspNetCoreComponentsWebAssemblyRuntimePackageVersion>3.2.0</MicrosoftAspNetCoreComponentsWebAssemblyRuntimePackageVersion>
|
||||||
<!-- Packages from dotnet/efcore -->
|
<!-- Packages from dotnet/efcore -->
|
||||||
<dotnetefPackageVersion>5.0.0-preview.7.20326.1</dotnetefPackageVersion>
|
<dotnetefPackageVersion>5.0.0-preview.8.20353.5</dotnetefPackageVersion>
|
||||||
<MicrosoftEntityFrameworkCoreInMemoryPackageVersion>5.0.0-preview.7.20326.1</MicrosoftEntityFrameworkCoreInMemoryPackageVersion>
|
<MicrosoftEntityFrameworkCoreInMemoryPackageVersion>5.0.0-preview.8.20353.5</MicrosoftEntityFrameworkCoreInMemoryPackageVersion>
|
||||||
<MicrosoftEntityFrameworkCoreRelationalPackageVersion>5.0.0-preview.7.20326.1</MicrosoftEntityFrameworkCoreRelationalPackageVersion>
|
<MicrosoftEntityFrameworkCoreRelationalPackageVersion>5.0.0-preview.8.20353.5</MicrosoftEntityFrameworkCoreRelationalPackageVersion>
|
||||||
<MicrosoftEntityFrameworkCoreSqlitePackageVersion>5.0.0-preview.7.20326.1</MicrosoftEntityFrameworkCoreSqlitePackageVersion>
|
<MicrosoftEntityFrameworkCoreSqlitePackageVersion>5.0.0-preview.8.20353.5</MicrosoftEntityFrameworkCoreSqlitePackageVersion>
|
||||||
<MicrosoftEntityFrameworkCoreSqlServerPackageVersion>5.0.0-preview.7.20326.1</MicrosoftEntityFrameworkCoreSqlServerPackageVersion>
|
<MicrosoftEntityFrameworkCoreSqlServerPackageVersion>5.0.0-preview.8.20353.5</MicrosoftEntityFrameworkCoreSqlServerPackageVersion>
|
||||||
<MicrosoftEntityFrameworkCoreToolsPackageVersion>5.0.0-preview.7.20326.1</MicrosoftEntityFrameworkCoreToolsPackageVersion>
|
<MicrosoftEntityFrameworkCoreToolsPackageVersion>5.0.0-preview.8.20353.5</MicrosoftEntityFrameworkCoreToolsPackageVersion>
|
||||||
<MicrosoftEntityFrameworkCorePackageVersion>5.0.0-preview.7.20326.1</MicrosoftEntityFrameworkCorePackageVersion>
|
<MicrosoftEntityFrameworkCorePackageVersion>5.0.0-preview.8.20353.5</MicrosoftEntityFrameworkCorePackageVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<!--
|
<!--
|
||||||
|
|
||||||
|
|
@ -189,16 +189,16 @@
|
||||||
<MicrosoftCodeAnalysisCSharpPackageVersion>3.4.0</MicrosoftCodeAnalysisCSharpPackageVersion>
|
<MicrosoftCodeAnalysisCSharpPackageVersion>3.4.0</MicrosoftCodeAnalysisCSharpPackageVersion>
|
||||||
<MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>3.4.0</MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>
|
<MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>3.4.0</MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>
|
||||||
<MicrosoftIdentityModelClientsActiveDirectoryPackageVersion>3.19.8</MicrosoftIdentityModelClientsActiveDirectoryPackageVersion>
|
<MicrosoftIdentityModelClientsActiveDirectoryPackageVersion>3.19.8</MicrosoftIdentityModelClientsActiveDirectoryPackageVersion>
|
||||||
<MicrosoftIdentityModelLoggingPackageVersion>6.6.0</MicrosoftIdentityModelLoggingPackageVersion>
|
<MicrosoftIdentityModelLoggingPackageVersion>5.5.0</MicrosoftIdentityModelLoggingPackageVersion>
|
||||||
<MicrosoftIdentityModelProtocolsOpenIdConnectPackageVersion>6.6.0</MicrosoftIdentityModelProtocolsOpenIdConnectPackageVersion>
|
<MicrosoftIdentityModelProtocolsOpenIdConnectPackageVersion>5.5.0</MicrosoftIdentityModelProtocolsOpenIdConnectPackageVersion>
|
||||||
<MicrosoftIdentityModelProtocolsWsFederationPackageVersion>6.6.0</MicrosoftIdentityModelProtocolsWsFederationPackageVersion>
|
<MicrosoftIdentityModelProtocolsWsFederationPackageVersion>5.5.0</MicrosoftIdentityModelProtocolsWsFederationPackageVersion>
|
||||||
<MicrosoftInternalAspNetCoreH2SpecAllPackageVersion>2.2.1</MicrosoftInternalAspNetCoreH2SpecAllPackageVersion>
|
<MicrosoftInternalAspNetCoreH2SpecAllPackageVersion>2.2.1</MicrosoftInternalAspNetCoreH2SpecAllPackageVersion>
|
||||||
<MicrosoftNETCoreWindowsApiSetsPackageVersion>1.0.1</MicrosoftNETCoreWindowsApiSetsPackageVersion>
|
<MicrosoftNETCoreWindowsApiSetsPackageVersion>1.0.1</MicrosoftNETCoreWindowsApiSetsPackageVersion>
|
||||||
<MicrosoftOwinSecurityCookiesPackageVersion>3.0.1</MicrosoftOwinSecurityCookiesPackageVersion>
|
<MicrosoftOwinSecurityCookiesPackageVersion>3.0.1</MicrosoftOwinSecurityCookiesPackageVersion>
|
||||||
<MicrosoftOwinTestingPackageVersion>3.0.1</MicrosoftOwinTestingPackageVersion>
|
<MicrosoftOwinTestingPackageVersion>3.0.1</MicrosoftOwinTestingPackageVersion>
|
||||||
<MicrosoftWebAdministrationPackageVersion>11.1.0</MicrosoftWebAdministrationPackageVersion>
|
<MicrosoftWebAdministrationPackageVersion>11.1.0</MicrosoftWebAdministrationPackageVersion>
|
||||||
<MicrosoftWebXdtPackageVersion>1.4.0</MicrosoftWebXdtPackageVersion>
|
<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 -->
|
<!-- Packages from 2.1/2.2 branches used for site extension build -->
|
||||||
<MicrosoftAspNetCoreAzureAppServicesSiteExtension21PackageVersion>2.1.1</MicrosoftAspNetCoreAzureAppServicesSiteExtension21PackageVersion>
|
<MicrosoftAspNetCoreAzureAppServicesSiteExtension21PackageVersion>2.1.1</MicrosoftAspNetCoreAzureAppServicesSiteExtension21PackageVersion>
|
||||||
<MicrosoftAspNetCoreAzureAppServicesSiteExtension22PackageVersion>2.2.0</MicrosoftAspNetCoreAzureAppServicesSiteExtension22PackageVersion>
|
<MicrosoftAspNetCoreAzureAppServicesSiteExtension22PackageVersion>2.2.0</MicrosoftAspNetCoreAzureAppServicesSiteExtension22PackageVersion>
|
||||||
|
|
@ -221,7 +221,7 @@
|
||||||
<IdentityServer4EntityFrameworkStoragePackageVersion>3.0.0</IdentityServer4EntityFrameworkStoragePackageVersion>
|
<IdentityServer4EntityFrameworkStoragePackageVersion>3.0.0</IdentityServer4EntityFrameworkStoragePackageVersion>
|
||||||
<MessagePackPackageVersion>2.1.90</MessagePackPackageVersion>
|
<MessagePackPackageVersion>2.1.90</MessagePackPackageVersion>
|
||||||
<MoqPackageVersion>4.10.0</MoqPackageVersion>
|
<MoqPackageVersion>4.10.0</MoqPackageVersion>
|
||||||
<MonoCecilPackageVersion>0.10.1</MonoCecilPackageVersion>
|
<MonoCecilPackageVersion>0.11.2</MonoCecilPackageVersion>
|
||||||
<NewtonsoftJsonBsonPackageVersion>1.0.2</NewtonsoftJsonBsonPackageVersion>
|
<NewtonsoftJsonBsonPackageVersion>1.0.2</NewtonsoftJsonBsonPackageVersion>
|
||||||
<NewtonsoftJsonPackageVersion>12.0.2</NewtonsoftJsonPackageVersion>
|
<NewtonsoftJsonPackageVersion>12.0.2</NewtonsoftJsonPackageVersion>
|
||||||
<!-- Begin: STOP!!! Razor need to reference the version of JSON that our HOSTS support. -->
|
<!-- 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>
|
</ItemGroup>
|
||||||
|
|
||||||
<!-- arm64 queues for helix-matrix.yml pipeline -->
|
<!-- 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="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" />
|
<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>
|
</ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -257,8 +257,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Compon
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Authentication", "Authentication", "{81250121-9B43-40B1-BF11-CE4458F2676C}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Authentication", "Authentication", "{81250121-9B43-40B1-BF11-CE4458F2676C}"
|
||||||
EndProject
|
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}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wasm.Authentication.Client", "WebAssembly\testassets\Wasm.Authentication.Client\Wasm.Authentication.Client.csproj", "{5F12F7B9-70BE-48F6-922A-3A1E87EE6BF0}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wasm.Authentication.Shared", "WebAssembly\testassets\Wasm.Authentication.Shared\Wasm.Authentication.Shared.csproj", "{630D5388-7A2F-42DD-9154-1F62A18CBB69}"
|
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|x64.Build.0 = Release|Any CPU
|
||||||
{6B0D6C08-FC30-4822-9464-4D24FF4CDC17}.Release|x86.ActiveCfg = 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
|
{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.ActiveCfg = Debug|Any CPU
|
||||||
{5F12F7B9-70BE-48F6-922A-3A1E87EE6BF0}.Debug|Any CPU.Build.0 = 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
|
{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}
|
{5CD61479-5181-4A5B-B90F-9F34316248B3} = {81250121-9B43-40B1-BF11-CE4458F2676C}
|
||||||
{6B0D6C08-FC30-4822-9464-4D24FF4CDC17} = {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}
|
{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}
|
{5F12F7B9-70BE-48F6-922A-3A1E87EE6BF0} = {A7ABAC29-F73F-456D-AE54-46842CFC2E10}
|
||||||
{630D5388-7A2F-42DD-9154-1F62A18CBB69} = {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}
|
{A062ACCE-AB0D-4569-9548-4BC0D9A9174B} = {2FC10057-7A0A-4E34-8302-879925BC0102}
|
||||||
|
|
|
||||||
|
|
@ -125,8 +125,14 @@ namespace Microsoft.AspNetCore.Components
|
||||||
private readonly object _dummy;
|
private readonly object _dummy;
|
||||||
private readonly int _dummyPrimitive;
|
private readonly int _dummyPrimitive;
|
||||||
public ElementReference(string id) { throw null; }
|
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 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)]
|
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
|
||||||
public readonly partial struct EventCallback
|
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 Renderer(System.IServiceProvider serviceProvider, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { }
|
||||||
public abstract Microsoft.AspNetCore.Components.Dispatcher Dispatcher { get; }
|
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 { } }
|
public event System.UnhandledExceptionEventHandler UnhandledSynchronizationException { add { } remove { } }
|
||||||
protected internal int AssignRootComponentId(Microsoft.AspNetCore.Components.IComponent component) { throw null; }
|
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; }
|
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 object _dummy;
|
||||||
private readonly int _dummyPrimitive;
|
private readonly int _dummyPrimitive;
|
||||||
public ElementReference(string id) { throw null; }
|
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 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)]
|
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
|
||||||
public readonly partial struct EventCallback
|
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 Renderer(System.IServiceProvider serviceProvider, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { }
|
||||||
public abstract Microsoft.AspNetCore.Components.Dispatcher Dispatcher { get; }
|
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 { } }
|
public event System.UnhandledExceptionEventHandler UnhandledSynchronizationException { add { } remove { } }
|
||||||
protected internal int AssignRootComponentId(Microsoft.AspNetCore.Components.IComponent component) { throw null; }
|
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; }
|
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>
|
/// </remarks>
|
||||||
public string Id { get; }
|
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;
|
Id = id;
|
||||||
|
Context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static ElementReference CreateWithUniqueId()
|
/// <summary>
|
||||||
=> new ElementReference(CreateUniqueId());
|
/// 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()
|
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>
|
<ItemGroup>
|
||||||
<Compile Include="$(ComponentsSharedSourceRoot)src\ArrayBuilder.cs" LinkBase="RenderTree" />
|
<Compile Include="$(ComponentsSharedSourceRoot)src\ArrayBuilder.cs" LinkBase="RenderTree" />
|
||||||
|
<Compile Include="$(ComponentsSharedSourceRoot)src\WebAssemblyJSInteropInternalCalls.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Components
|
||||||
|
|
||||||
static PlatformInfo()
|
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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using Microsoft.AspNetCore.Components.Profiling;
|
||||||
using Microsoft.AspNetCore.Components.Rendering;
|
using Microsoft.AspNetCore.Components.Rendering;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Components.RenderTree
|
namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
|
|
@ -25,6 +28,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
ArrayRange<RenderTreeFrame> oldTree,
|
ArrayRange<RenderTreeFrame> oldTree,
|
||||||
ArrayRange<RenderTreeFrame> newTree)
|
ArrayRange<RenderTreeFrame> newTree)
|
||||||
{
|
{
|
||||||
|
ComponentsProfiling.Instance.Start();
|
||||||
var editsBuffer = batchBuilder.EditsBuffer;
|
var editsBuffer = batchBuilder.EditsBuffer;
|
||||||
var editsBufferStartLength = editsBuffer.Count;
|
var editsBufferStartLength = editsBuffer.Count;
|
||||||
|
|
||||||
|
|
@ -32,7 +36,9 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
AppendDiffEntriesForRange(ref diffContext, 0, oldTree.Count, 0, newTree.Count);
|
AppendDiffEntriesForRange(ref diffContext, 0, oldTree.Count, 0, newTree.Count);
|
||||||
|
|
||||||
var editsSegment = editsBuffer.ToSegment(editsBufferStartLength, editsBuffer.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)
|
public static void DisposeFrames(RenderBatchBuilder batchBuilder, ArrayRange<RenderTreeFrame> frames)
|
||||||
|
|
@ -43,6 +49,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
int oldStartIndex, int oldEndIndexExcl,
|
int oldStartIndex, int oldEndIndexExcl,
|
||||||
int newStartIndex, int newEndIndexExcl)
|
int newStartIndex, int newEndIndexExcl)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
// This is deliberately a very large method. Parts of it could be factored out
|
// 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,
|
// 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
|
// 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);
|
diffContext.KeyedItemInfoDictionaryPool.Return(keyedItemInfos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Dictionary<object, KeyedItemInfo> BuildKeyToInfoLookup(DiffContext diffContext, int oldStartIndex, int oldEndIndexExcl, int newStartIndex, int newEndIndexExcl)
|
private static Dictionary<object, KeyedItemInfo> BuildKeyToInfoLookup(DiffContext diffContext, int oldStartIndex, int oldEndIndexExcl, int newStartIndex, int newEndIndexExcl)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
var result = diffContext.KeyedItemInfoDictionaryPool.Get();
|
var result = diffContext.KeyedItemInfoDictionaryPool.Get();
|
||||||
var oldTree = diffContext.OldTree;
|
var oldTree = diffContext.OldTree;
|
||||||
var newTree = diffContext.NewTree;
|
var newTree = diffContext.NewTree;
|
||||||
|
|
@ -342,6 +351,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
newStartIndex = NextSiblingIndex(frame, newStartIndex);
|
newStartIndex = NextSiblingIndex(frame, newStartIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProfilingEnd();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -374,6 +384,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
int oldStartIndex, int oldEndIndexExcl,
|
int oldStartIndex, int oldEndIndexExcl,
|
||||||
int newStartIndex, int newEndIndexExcl)
|
int newStartIndex, int newEndIndexExcl)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
// The overhead of the dictionary used by AppendAttributeDiffEntriesForRangeSlow is
|
// 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
|
// 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
|
// 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,
|
ref diffContext,
|
||||||
oldStartIndex, oldEndIndexExcl,
|
oldStartIndex, oldEndIndexExcl,
|
||||||
newStartIndex, newEndIndexExcl);
|
newStartIndex, newEndIndexExcl);
|
||||||
|
ProfilingEnd();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -447,9 +459,12 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
ref diffContext,
|
ref diffContext,
|
||||||
oldStartIndex, oldEndIndexExcl,
|
oldStartIndex, oldEndIndexExcl,
|
||||||
newStartIndex, newEndIndexExcl);
|
newStartIndex, newEndIndexExcl);
|
||||||
|
ProfilingEnd();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AppendAttributeDiffEntriesForRangeSlow(
|
private static void AppendAttributeDiffEntriesForRangeSlow(
|
||||||
|
|
@ -457,6 +472,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
int oldStartIndex, int oldEndIndexExcl,
|
int oldStartIndex, int oldEndIndexExcl,
|
||||||
int newStartIndex, int newEndIndexExcl)
|
int newStartIndex, int newEndIndexExcl)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
var oldTree = diffContext.OldTree;
|
var oldTree = diffContext.OldTree;
|
||||||
var newTree = diffContext.NewTree;
|
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.
|
// We should have processed any additions at this point. Reset for the next batch.
|
||||||
diffContext.AttributeDiffSet.Clear();
|
diffContext.AttributeDiffSet.Clear();
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void UpdateRetainedChildComponent(
|
private static void UpdateRetainedChildComponent(
|
||||||
|
|
@ -502,6 +519,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
int oldComponentIndex,
|
int oldComponentIndex,
|
||||||
int newComponentIndex)
|
int newComponentIndex)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
var oldTree = diffContext.OldTree;
|
var oldTree = diffContext.OldTree;
|
||||||
var newTree = diffContext.NewTree;
|
var newTree = diffContext.NewTree;
|
||||||
ref var oldComponentFrame = ref oldTree[oldComponentIndex];
|
ref var oldComponentFrame = ref oldTree[oldComponentIndex];
|
||||||
|
|
@ -528,6 +546,8 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
{
|
{
|
||||||
componentState.SetDirectParameters(newParameters);
|
componentState.SetDirectParameters(newParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int NextSiblingIndex(in RenderTreeFrame frame, int frameIndex)
|
private static int NextSiblingIndex(in RenderTreeFrame frame, int frameIndex)
|
||||||
|
|
@ -550,6 +570,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
int oldFrameIndex,
|
int oldFrameIndex,
|
||||||
int newFrameIndex)
|
int newFrameIndex)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
var oldTree = diffContext.OldTree;
|
var oldTree = diffContext.OldTree;
|
||||||
var newTree = diffContext.NewTree;
|
var newTree = diffContext.NewTree;
|
||||||
ref var oldFrame = ref oldTree[oldFrameIndex];
|
ref var oldFrame = ref oldTree[oldFrameIndex];
|
||||||
|
|
@ -562,6 +583,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
{
|
{
|
||||||
InsertNewFrame(ref diffContext, newFrameIndex);
|
InsertNewFrame(ref diffContext, newFrameIndex);
|
||||||
RemoveOldFrame(ref diffContext, oldFrameIndex);
|
RemoveOldFrame(ref diffContext, oldFrameIndex);
|
||||||
|
ProfilingEnd();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -687,6 +709,8 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
default:
|
default:
|
||||||
throw new NotImplementedException($"Encountered unsupported frame type during diffing: {newTree[newFrameIndex].FrameType}");
|
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
|
// 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 oldFrameIndex,
|
||||||
int newFrameIndex)
|
int newFrameIndex)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
var oldTree = diffContext.OldTree;
|
var oldTree = diffContext.OldTree;
|
||||||
var newTree = diffContext.NewTree;
|
var newTree = diffContext.NewTree;
|
||||||
ref var oldFrame = ref oldTree[oldFrameIndex];
|
ref var oldFrame = ref oldTree[oldFrameIndex];
|
||||||
|
|
@ -724,10 +749,13 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
// since it was unchanged.
|
// since it was unchanged.
|
||||||
newFrame = oldFrame;
|
newFrame = oldFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void InsertNewFrame(ref DiffContext diffContext, int newFrameIndex)
|
private static void InsertNewFrame(ref DiffContext diffContext, int newFrameIndex)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
var newTree = diffContext.NewTree;
|
var newTree = diffContext.NewTree;
|
||||||
ref var newFrame = ref newTree[newFrameIndex];
|
ref var newFrame = ref newTree[newFrameIndex];
|
||||||
switch (newFrame.FrameType)
|
switch (newFrame.FrameType)
|
||||||
|
|
@ -780,10 +808,12 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
default:
|
default:
|
||||||
throw new NotImplementedException($"Unexpected frame type during {nameof(InsertNewFrame)}: {newFrame.FrameType}");
|
throw new NotImplementedException($"Unexpected frame type during {nameof(InsertNewFrame)}: {newFrame.FrameType}");
|
||||||
}
|
}
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RemoveOldFrame(ref DiffContext diffContext, int oldFrameIndex)
|
private static void RemoveOldFrame(ref DiffContext diffContext, int oldFrameIndex)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
var oldTree = diffContext.OldTree;
|
var oldTree = diffContext.OldTree;
|
||||||
ref var oldFrame = ref oldTree[oldFrameIndex];
|
ref var oldFrame = ref oldTree[oldFrameIndex];
|
||||||
switch (oldFrame.FrameType)
|
switch (oldFrame.FrameType)
|
||||||
|
|
@ -825,6 +855,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
default:
|
default:
|
||||||
throw new NotImplementedException($"Unexpected frame type during {nameof(RemoveOldFrame)}: {oldFrame.FrameType}");
|
throw new NotImplementedException($"Unexpected frame type during {nameof(RemoveOldFrame)}: {oldFrame.FrameType}");
|
||||||
}
|
}
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int GetAttributesEndIndexExclusive(RenderTreeFrame[] tree, int rootIndex)
|
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)
|
private static void InitializeNewSubtree(ref DiffContext diffContext, int frameIndex)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
var frames = diffContext.NewTree;
|
var frames = diffContext.NewTree;
|
||||||
var endIndexExcl = frameIndex + frames[frameIndex].ElementSubtreeLength;
|
var endIndexExcl = frameIndex + frames[frameIndex].ElementSubtreeLength;
|
||||||
for (var i = frameIndex; i < endIndexExcl; i++)
|
for (var i = frameIndex; i < endIndexExcl; i++)
|
||||||
|
|
@ -879,10 +911,12 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void InitializeNewComponentFrame(ref DiffContext diffContext, int frameIndex)
|
private static void InitializeNewComponentFrame(ref DiffContext diffContext, int frameIndex)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
var frames = diffContext.NewTree;
|
var frames = diffContext.NewTree;
|
||||||
ref var frame = ref frames[frameIndex];
|
ref var frame = ref frames[frameIndex];
|
||||||
|
|
||||||
|
|
@ -899,6 +933,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
var initialParametersLifetime = new ParameterViewLifetime(diffContext.BatchBuilder);
|
var initialParametersLifetime = new ParameterViewLifetime(diffContext.BatchBuilder);
|
||||||
var initialParameters = new ParameterView(initialParametersLifetime, frames, frameIndex);
|
var initialParameters = new ParameterView(initialParametersLifetime, frames, frameIndex);
|
||||||
childComponentState.SetDirectParameters(initialParameters);
|
childComponentState.SetDirectParameters(initialParameters);
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void InitializeNewAttributeFrame(ref DiffContext diffContext, ref RenderTreeFrame newFrame)
|
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)
|
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 = newFrame.WithElementReferenceCaptureId(newElementReference.Id);
|
||||||
newFrame.ElementReferenceCaptureAction(newElementReference);
|
newFrame.ElementReferenceCaptureAction(newElementReference);
|
||||||
}
|
}
|
||||||
|
|
@ -943,6 +978,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
|
|
||||||
private static void DisposeFramesInRange(RenderBatchBuilder batchBuilder, RenderTreeFrame[] frames, int startIndex, int endIndexExcl)
|
private static void DisposeFramesInRange(RenderBatchBuilder batchBuilder, RenderTreeFrame[] frames, int startIndex, int endIndexExcl)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
for (var i = startIndex; i < endIndexExcl; i++)
|
for (var i = startIndex; i < endIndexExcl; i++)
|
||||||
{
|
{
|
||||||
ref var frame = ref frames[i];
|
ref var frame = ref frames[i];
|
||||||
|
|
@ -955,6 +991,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
batchBuilder.DisposedEventHandlerIds.Append(frame.AttributeEventHandlerId);
|
batchBuilder.DisposedEventHandlerIds.Append(frame.AttributeEventHandlerId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -996,5 +1033,18 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
SiblingIndex = 0;
|
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.Diagnostics;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Components.Profiling;
|
||||||
using Microsoft.AspNetCore.Components.Rendering;
|
using Microsoft.AspNetCore.Components.Rendering;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
|
@ -76,6 +77,12 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract Dispatcher Dispatcher { get; }
|
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>
|
/// <summary>
|
||||||
/// Constructs a new component of the specified type.
|
/// Constructs a new component of the specified type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -214,6 +221,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public virtual Task DispatchEventAsync(ulong eventHandlerId, EventFieldInfo fieldInfo, EventArgs eventArgs)
|
public virtual Task DispatchEventAsync(ulong eventHandlerId, EventFieldInfo fieldInfo, EventArgs eventArgs)
|
||||||
{
|
{
|
||||||
|
ComponentsProfiling.Instance.Start();
|
||||||
Dispatcher.AssertAccess();
|
Dispatcher.AssertAccess();
|
||||||
|
|
||||||
if (!_eventBindings.TryGetValue(eventHandlerId, out var callback))
|
if (!_eventBindings.TryGetValue(eventHandlerId, out var callback))
|
||||||
|
|
@ -241,6 +249,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
HandleException(e);
|
HandleException(e);
|
||||||
|
ComponentsProfiling.Instance.End();
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|
@ -254,7 +263,9 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
|
|
||||||
// Task completed synchronously or is still running. We already processed all of the rendering
|
// 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.
|
// 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)
|
internal void InstantiateChildComponentOnFrame(ref RenderTreeFrame frame, int parentComponentId)
|
||||||
|
|
@ -404,6 +415,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
|
|
||||||
private void ProcessRenderQueue()
|
private void ProcessRenderQueue()
|
||||||
{
|
{
|
||||||
|
ComponentsProfiling.Instance.Start();
|
||||||
Dispatcher.AssertAccess();
|
Dispatcher.AssertAccess();
|
||||||
|
|
||||||
if (_isBatchInProgress)
|
if (_isBatchInProgress)
|
||||||
|
|
@ -418,6 +430,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
{
|
{
|
||||||
if (_batchBuilder.ComponentRenderQueue.Count == 0)
|
if (_batchBuilder.ComponentRenderQueue.Count == 0)
|
||||||
{
|
{
|
||||||
|
ComponentsProfiling.Instance.End();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -429,7 +442,9 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
}
|
}
|
||||||
|
|
||||||
var batch = _batchBuilder.ToBatch();
|
var batch = _batchBuilder.ToBatch();
|
||||||
|
ComponentsProfiling.Instance.Start(nameof(UpdateDisplayAsync));
|
||||||
updateDisplayTask = UpdateDisplayAsync(batch);
|
updateDisplayTask = UpdateDisplayAsync(batch);
|
||||||
|
ComponentsProfiling.Instance.End(nameof(UpdateDisplayAsync));
|
||||||
|
|
||||||
// Fire off the execution of OnAfterRenderAsync, but don't wait for it
|
// Fire off the execution of OnAfterRenderAsync, but don't wait for it
|
||||||
// if there is async work to be done.
|
// 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.
|
// Ensure we catch errors while running the render functions of the components.
|
||||||
HandleException(e);
|
HandleException(e);
|
||||||
|
ComponentsProfiling.Instance.End();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|
@ -456,6 +472,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
{
|
{
|
||||||
ProcessRenderQueue();
|
ProcessRenderQueue();
|
||||||
}
|
}
|
||||||
|
ComponentsProfiling.Instance.End();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task InvokeRenderCompletedCalls(ArrayRange<RenderTreeDiff> updatedComponents, Task updateDisplayTask)
|
private Task InvokeRenderCompletedCalls(ArrayRange<RenderTreeDiff> updatedComponents, Task updateDisplayTask)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Components.Profiling;
|
||||||
using Microsoft.AspNetCore.Components.RenderTree;
|
using Microsoft.AspNetCore.Components.RenderTree;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Components.Rendering
|
namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
|
|
@ -56,6 +57,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
|
|
||||||
public void RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment)
|
public void RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment)
|
||||||
{
|
{
|
||||||
|
ComponentsProfiling.Instance.Start();
|
||||||
// A component might be in the render queue already before getting disposed by an
|
// 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.
|
// earlier entry in the render queue. In that case, rendering is a no-op.
|
||||||
if (_componentWasDisposed)
|
if (_componentWasDisposed)
|
||||||
|
|
@ -67,7 +69,9 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
(CurrentRenderTree, _renderTreeBuilderPrevious) = (_renderTreeBuilderPrevious, CurrentRenderTree);
|
(CurrentRenderTree, _renderTreeBuilderPrevious) = (_renderTreeBuilderPrevious, CurrentRenderTree);
|
||||||
|
|
||||||
CurrentRenderTree.Clear();
|
CurrentRenderTree.Clear();
|
||||||
|
ComponentsProfiling.Instance.Start("BuildRenderTree");
|
||||||
renderFragment(CurrentRenderTree);
|
renderFragment(CurrentRenderTree);
|
||||||
|
ComponentsProfiling.Instance.End("BuildRenderTree");
|
||||||
|
|
||||||
var diff = RenderTreeDiffBuilder.ComputeDiff(
|
var diff = RenderTreeDiffBuilder.ComputeDiff(
|
||||||
_renderer,
|
_renderer,
|
||||||
|
|
@ -77,6 +81,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
CurrentRenderTree.GetFrames());
|
CurrentRenderTree.GetFrames());
|
||||||
batchBuilder.UpdatedComponentDiffs.Append(diff);
|
batchBuilder.UpdatedComponentDiffs.Append(diff);
|
||||||
batchBuilder.InvalidateParameterViews();
|
batchBuilder.InvalidateParameterViews();
|
||||||
|
ComponentsProfiling.Instance.End();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryDisposeInBatch(RenderBatchBuilder batchBuilder, [NotNullWhen(false)] out Exception? exception)
|
public bool TryDisposeInBatch(RenderBatchBuilder batchBuilder, [NotNullWhen(false)] out Exception? exception)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using Microsoft.AspNetCore.Components.Profiling;
|
||||||
using Microsoft.AspNetCore.Components.RenderTree;
|
using Microsoft.AspNetCore.Components.RenderTree;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Components.Rendering
|
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>
|
/// <param name="elementName">A value representing the type of the element.</param>
|
||||||
public void OpenElement(int sequence, string elementName)
|
public void OpenElement(int sequence, string elementName)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
// We are entering a new scope, since we track the "duplicate attributes" per
|
// We are entering a new scope, since we track the "duplicate attributes" per
|
||||||
// element/component we might need to clean them up now.
|
// element/component we might need to clean them up now.
|
||||||
if (_hasSeenAddMultipleAttributes)
|
if (_hasSeenAddMultipleAttributes)
|
||||||
|
|
@ -53,6 +56,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
|
|
||||||
_openElementIndices.Push(_entries.Count);
|
_openElementIndices.Push(_entries.Count);
|
||||||
Append(RenderTreeFrame.Element(sequence, elementName));
|
Append(RenderTreeFrame.Element(sequence, elementName));
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -61,6 +65,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void CloseElement()
|
public void CloseElement()
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
var indexOfEntryBeingClosed = _openElementIndices.Pop();
|
var indexOfEntryBeingClosed = _openElementIndices.Pop();
|
||||||
|
|
||||||
// We might be closing an element with only attributes, run the duplicate cleanup pass
|
// 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];
|
ref var entry = ref _entries.Buffer[indexOfEntryBeingClosed];
|
||||||
entry = entry.WithElementSubtreeLength(_entries.Count - indexOfEntryBeingClosed);
|
entry = entry.WithElementSubtreeLength(_entries.Count - indexOfEntryBeingClosed);
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <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="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>
|
/// <param name="markupContent">Content for the new markup frame.</param>
|
||||||
public void AddMarkupContent(int sequence, string? markupContent)
|
public void AddMarkupContent(int sequence, string? markupContent)
|
||||||
=> Append(RenderTreeFrame.Markup(sequence, markupContent ?? string.Empty));
|
{
|
||||||
|
ProfilingStart();
|
||||||
|
Append(RenderTreeFrame.Markup(sequence, markupContent ?? string.Empty));
|
||||||
|
ProfilingEnd();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Appends a frame representing text content.
|
/// 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="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>
|
/// <param name="textContent">Content for the new text frame.</param>
|
||||||
public void AddContent(int sequence, string? textContent)
|
public void AddContent(int sequence, string? textContent)
|
||||||
=> Append(RenderTreeFrame.Text(sequence, textContent ?? string.Empty));
|
{
|
||||||
|
ProfilingStart();
|
||||||
|
Append(RenderTreeFrame.Text(sequence, textContent ?? string.Empty));
|
||||||
|
ProfilingEnd();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Appends frames representing an arbitrary fragment of content.
|
/// Appends frames representing an arbitrary fragment of content.
|
||||||
|
|
@ -97,6 +111,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
/// <param name="fragment">Content to append.</param>
|
/// <param name="fragment">Content to append.</param>
|
||||||
public void AddContent(int sequence, RenderFragment? fragment)
|
public void AddContent(int sequence, RenderFragment? fragment)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
if (fragment != null)
|
if (fragment != null)
|
||||||
{
|
{
|
||||||
// We surround the fragment with a region delimiter to indicate that the
|
// We surround the fragment with a region delimiter to indicate that the
|
||||||
|
|
@ -107,6 +122,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
fragment(this);
|
fragment(this);
|
||||||
CloseRegion();
|
CloseRegion();
|
||||||
}
|
}
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -117,10 +133,12 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
/// <param name="value">The value used by <paramref name="fragment"/>.</param>
|
/// <param name="value">The value used by <paramref name="fragment"/>.</param>
|
||||||
public void AddContent<TValue>(int sequence, RenderFragment<TValue>? fragment, TValue value)
|
public void AddContent<TValue>(int sequence, RenderFragment<TValue>? fragment, TValue value)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
if (fragment != null)
|
if (fragment != null)
|
||||||
{
|
{
|
||||||
AddContent(sequence, fragment(value));
|
AddContent(sequence, fragment(value));
|
||||||
}
|
}
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -153,6 +171,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
/// <param name="value">The value of the attribute.</param>
|
/// <param name="value">The value of the attribute.</param>
|
||||||
public void AddAttribute(int sequence, string name, bool value)
|
public void AddAttribute(int sequence, string name, bool value)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
AssertCanAddAttribute();
|
AssertCanAddAttribute();
|
||||||
if (_lastNonAttributeFrameType == RenderTreeFrameType.Component)
|
if (_lastNonAttributeFrameType == RenderTreeFrameType.Component)
|
||||||
{
|
{
|
||||||
|
|
@ -168,6 +187,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
{
|
{
|
||||||
TrackAttributeName(name);
|
TrackAttributeName(name);
|
||||||
}
|
}
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -184,6 +204,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
/// <param name="value">The value of the attribute.</param>
|
/// <param name="value">The value of the attribute.</param>
|
||||||
public void AddAttribute(int sequence, string name, string? value)
|
public void AddAttribute(int sequence, string name, string? value)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
AssertCanAddAttribute();
|
AssertCanAddAttribute();
|
||||||
if (value != null || _lastNonAttributeFrameType == RenderTreeFrameType.Component)
|
if (value != null || _lastNonAttributeFrameType == RenderTreeFrameType.Component)
|
||||||
{
|
{
|
||||||
|
|
@ -193,6 +214,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
{
|
{
|
||||||
TrackAttributeName(name);
|
TrackAttributeName(name);
|
||||||
}
|
}
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -209,6 +231,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
/// <param name="value">The value of the attribute.</param>
|
/// <param name="value">The value of the attribute.</param>
|
||||||
public void AddAttribute(int sequence, string name, MulticastDelegate? value)
|
public void AddAttribute(int sequence, string name, MulticastDelegate? value)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
AssertCanAddAttribute();
|
AssertCanAddAttribute();
|
||||||
if (value != null || _lastNonAttributeFrameType == RenderTreeFrameType.Component)
|
if (value != null || _lastNonAttributeFrameType == RenderTreeFrameType.Component)
|
||||||
{
|
{
|
||||||
|
|
@ -218,6 +241,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
{
|
{
|
||||||
TrackAttributeName(name);
|
TrackAttributeName(name);
|
||||||
}
|
}
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -238,6 +262,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public void AddAttribute(int sequence, string name, EventCallback value)
|
public void AddAttribute(int sequence, string name, EventCallback value)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
AssertCanAddAttribute();
|
AssertCanAddAttribute();
|
||||||
if (_lastNonAttributeFrameType == RenderTreeFrameType.Component)
|
if (_lastNonAttributeFrameType == RenderTreeFrameType.Component)
|
||||||
{
|
{
|
||||||
|
|
@ -262,6 +287,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
// Track the attribute name if needed since we elided the frame.
|
// Track the attribute name if needed since we elided the frame.
|
||||||
TrackAttributeName(name);
|
TrackAttributeName(name);
|
||||||
}
|
}
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -282,6 +308,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public void AddAttribute<TArgument>(int sequence, string name, EventCallback<TArgument> value)
|
public void AddAttribute<TArgument>(int sequence, string name, EventCallback<TArgument> value)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
AssertCanAddAttribute();
|
AssertCanAddAttribute();
|
||||||
if (_lastNonAttributeFrameType == RenderTreeFrameType.Component)
|
if (_lastNonAttributeFrameType == RenderTreeFrameType.Component)
|
||||||
{
|
{
|
||||||
|
|
@ -306,6 +333,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
// Track the attribute name if needed since we elided the frame.
|
// Track the attribute name if needed since we elided the frame.
|
||||||
TrackAttributeName(name);
|
TrackAttributeName(name);
|
||||||
}
|
}
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -319,6 +347,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
/// <param name="value">The value of the attribute.</param>
|
/// <param name="value">The value of the attribute.</param>
|
||||||
public void AddAttribute(int sequence, string name, object? value)
|
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
|
// This looks a bit daunting because we need to handle the boxed/object version of all of the
|
||||||
// types that AddAttribute special cases.
|
// types that AddAttribute special cases.
|
||||||
if (_lastNonAttributeFrameType == RenderTreeFrameType.Element)
|
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.
|
// This is going to throw. Calling it just to get a consistent exception message.
|
||||||
AssertCanAddAttribute();
|
AssertCanAddAttribute();
|
||||||
}
|
}
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <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>
|
/// <param name="frame">A <see cref="RenderTreeFrame"/> holding the name and value of the attribute.</param>
|
||||||
public void AddAttribute(int sequence, in RenderTreeFrame frame)
|
public void AddAttribute(int sequence, in RenderTreeFrame frame)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
if (frame.FrameType != RenderTreeFrameType.Attribute)
|
if (frame.FrameType != RenderTreeFrameType.Attribute)
|
||||||
{
|
{
|
||||||
throw new ArgumentException($"The {nameof(frame.FrameType)} must be {RenderTreeFrameType.Attribute}.");
|
throw new ArgumentException($"The {nameof(frame.FrameType)} must be {RenderTreeFrameType.Attribute}.");
|
||||||
|
|
@ -392,6 +423,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
|
|
||||||
AssertCanAddAttribute();
|
AssertCanAddAttribute();
|
||||||
Append(frame.WithAttributeSequence(sequence));
|
Append(frame.WithAttributeSequence(sequence));
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -401,6 +433,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
/// <param name="attributes">A collection of key-value pairs representing attributes.</param>
|
/// <param name="attributes">A collection of key-value pairs representing attributes.</param>
|
||||||
public void AddMultipleAttributes(int sequence, IEnumerable<KeyValuePair<string, object>>? attributes)
|
public void AddMultipleAttributes(int sequence, IEnumerable<KeyValuePair<string, object>>? attributes)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
// Calling this up-front just to make sure we validate before mutating anything.
|
// Calling this up-front just to make sure we validate before mutating anything.
|
||||||
AssertCanAddAttribute();
|
AssertCanAddAttribute();
|
||||||
|
|
||||||
|
|
@ -417,6 +450,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
AddAttribute(sequence, attribute.Key, attribute.Value);
|
AddAttribute(sequence, attribute.Key, attribute.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <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>
|
/// <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)
|
public void SetUpdatesAttributeName(string updatesAttributeName)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
if (_entries.Count == 0)
|
if (_entries.Count == 0)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("No preceding attribute frame exists.");
|
throw new InvalidOperationException("No preceding attribute frame exists.");
|
||||||
|
|
@ -445,6 +480,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
}
|
}
|
||||||
|
|
||||||
prevFrame = prevFrame.WithAttributeEventUpdatesAttributeName(updatesAttributeName);
|
prevFrame = prevFrame.WithAttributeEventUpdatesAttributeName(updatesAttributeName);
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -476,10 +512,12 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
/// <param name="value">The value for the key.</param>
|
/// <param name="value">The value for the key.</param>
|
||||||
public void SetKey(object? value)
|
public void SetKey(object? value)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
if (value == null)
|
if (value == null)
|
||||||
{
|
{
|
||||||
// Null is equivalent to not having set a key, which is valuable because Razor syntax doesn't have an
|
// 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
|
// easy way to have conditional directive attributes
|
||||||
|
ProfilingEnd();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -502,10 +540,12 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
default:
|
default:
|
||||||
throw new InvalidOperationException($"Cannot set a key on a frame of type {parentFrame.FrameType}.");
|
throw new InvalidOperationException($"Cannot set a key on a frame of type {parentFrame.FrameType}.");
|
||||||
}
|
}
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OpenComponentUnchecked(int sequence, Type componentType)
|
private void OpenComponentUnchecked(int sequence, Type componentType)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
// We are entering a new scope, since we track the "duplicate attributes" per
|
// We are entering a new scope, since we track the "duplicate attributes" per
|
||||||
// element/component we might need to clean them up now.
|
// element/component we might need to clean them up now.
|
||||||
if (_hasSeenAddMultipleAttributes)
|
if (_hasSeenAddMultipleAttributes)
|
||||||
|
|
@ -516,6 +556,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
|
|
||||||
_openElementIndices.Push(_entries.Count);
|
_openElementIndices.Push(_entries.Count);
|
||||||
Append(RenderTreeFrame.ChildComponent(sequence, componentType));
|
Append(RenderTreeFrame.ChildComponent(sequence, componentType));
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -524,6 +565,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void CloseComponent()
|
public void CloseComponent()
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
var indexOfEntryBeingClosed = _openElementIndices.Pop();
|
var indexOfEntryBeingClosed = _openElementIndices.Pop();
|
||||||
|
|
||||||
// We might be closing a component with only attributes. Run the attribute cleanup pass
|
// 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];
|
ref var entry = ref _entries.Buffer[indexOfEntryBeingClosed];
|
||||||
entry = entry.WithComponentSubtreeLength(_entries.Count - indexOfEntryBeingClosed);
|
entry = entry.WithComponentSubtreeLength(_entries.Count - indexOfEntryBeingClosed);
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -544,12 +587,14 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
/// <param name="elementReferenceCaptureAction">An action to be invoked whenever the reference value changes.</param>
|
/// <param name="elementReferenceCaptureAction">An action to be invoked whenever the reference value changes.</param>
|
||||||
public void AddElementReferenceCapture(int sequence, Action<ElementReference> elementReferenceCaptureAction)
|
public void AddElementReferenceCapture(int sequence, Action<ElementReference> elementReferenceCaptureAction)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
if (GetCurrentParentFrameType() != RenderTreeFrameType.Element)
|
if (GetCurrentParentFrameType() != RenderTreeFrameType.Element)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Element reference captures may only be added as children of frames of type {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));
|
Append(RenderTreeFrame.ElementReferenceCapture(sequence, elementReferenceCaptureAction));
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -559,6 +604,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
/// <param name="componentReferenceCaptureAction">An action to be invoked whenever the reference value changes.</param>
|
/// <param name="componentReferenceCaptureAction">An action to be invoked whenever the reference value changes.</param>
|
||||||
public void AddComponentReferenceCapture(int sequence, Action<object?> componentReferenceCaptureAction)
|
public void AddComponentReferenceCapture(int sequence, Action<object?> componentReferenceCaptureAction)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
var parentFrameIndex = GetCurrentParentFrameIndex();
|
var parentFrameIndex = GetCurrentParentFrameIndex();
|
||||||
if (!parentFrameIndex.HasValue)
|
if (!parentFrameIndex.HasValue)
|
||||||
{
|
{
|
||||||
|
|
@ -572,6 +618,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
}
|
}
|
||||||
|
|
||||||
Append(RenderTreeFrame.ComponentReferenceCapture(sequence, componentReferenceCaptureAction, parentFrameIndexValue));
|
Append(RenderTreeFrame.ComponentReferenceCapture(sequence, componentReferenceCaptureAction, parentFrameIndexValue));
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <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>
|
/// <param name="sequence">An integer that represents the position of the instruction in the source code.</param>
|
||||||
public void OpenRegion(int sequence)
|
public void OpenRegion(int sequence)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
// We are entering a new scope, since we track the "duplicate attributes" per
|
// We are entering a new scope, since we track the "duplicate attributes" per
|
||||||
// element/component we might need to clean them up now.
|
// element/component we might need to clean them up now.
|
||||||
if (_hasSeenAddMultipleAttributes)
|
if (_hasSeenAddMultipleAttributes)
|
||||||
|
|
@ -590,6 +638,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
|
|
||||||
_openElementIndices.Push(_entries.Count);
|
_openElementIndices.Push(_entries.Count);
|
||||||
Append(RenderTreeFrame.Region(sequence));
|
Append(RenderTreeFrame.Region(sequence));
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -598,9 +647,11 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void CloseRegion()
|
public void CloseRegion()
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
var indexOfEntryBeingClosed = _openElementIndices.Pop();
|
var indexOfEntryBeingClosed = _openElementIndices.Pop();
|
||||||
ref var entry = ref _entries.Buffer[indexOfEntryBeingClosed];
|
ref var entry = ref _entries.Buffer[indexOfEntryBeingClosed];
|
||||||
entry = entry.WithRegionSubtreeLength(_entries.Count - indexOfEntryBeingClosed);
|
entry = entry.WithRegionSubtreeLength(_entries.Count - indexOfEntryBeingClosed);
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AssertCanAddAttribute()
|
private void AssertCanAddAttribute()
|
||||||
|
|
@ -628,24 +679,29 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
_entries.Clear();
|
_entries.Clear();
|
||||||
_openElementIndices.Clear();
|
_openElementIndices.Clear();
|
||||||
_lastNonAttributeFrameType = null;
|
_lastNonAttributeFrameType = null;
|
||||||
_hasSeenAddMultipleAttributes = false;
|
_hasSeenAddMultipleAttributes = false;
|
||||||
_seenAttributeNames?.Clear();
|
_seenAttributeNames?.Clear();
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
// internal because this should only be used during the post-event tree patching logic
|
// 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
|
// 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)
|
internal void InsertAttributeExpensive(int insertAtIndex, int sequence, string attributeName, object? attributeValue)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
// Replicate the same attribute omission logic as used elsewhere
|
// Replicate the same attribute omission logic as used elsewhere
|
||||||
if ((attributeValue == null) || (attributeValue is bool boolValue && !boolValue))
|
if ((attributeValue == null) || (attributeValue is bool boolValue && !boolValue))
|
||||||
{
|
{
|
||||||
|
ProfilingEnd();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_entries.InsertExpensive(insertAtIndex, RenderTreeFrame.Attribute(sequence, attributeName, attributeValue));
|
_entries.InsertExpensive(insertAtIndex, RenderTreeFrame.Attribute(sequence, attributeName, attributeValue));
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -669,6 +725,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
// Internal for testing
|
// Internal for testing
|
||||||
internal void ProcessDuplicateAttributes(int first)
|
internal void ProcessDuplicateAttributes(int first)
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
Debug.Assert(_hasSeenAddMultipleAttributes);
|
Debug.Assert(_hasSeenAddMultipleAttributes);
|
||||||
|
|
||||||
// When AddMultipleAttributes method has been called, we need to postprocess attributes while closing
|
// When AddMultipleAttributes method has been called, we need to postprocess attributes while closing
|
||||||
|
|
@ -750,6 +807,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
|
|
||||||
seenAttributeNames.Clear();
|
seenAttributeNames.Clear();
|
||||||
_hasSeenAddMultipleAttributes = false;
|
_hasSeenAddMultipleAttributes = false;
|
||||||
|
ProfilingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal for testing
|
// Internal for testing
|
||||||
|
|
@ -766,7 +824,22 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
|
|
||||||
void IDisposable.Dispose()
|
void IDisposable.Dispose()
|
||||||
{
|
{
|
||||||
|
ProfilingStart();
|
||||||
_entries.Dispose();
|
_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;
|
Thread capturedThread = null;
|
||||||
|
|
||||||
var e = new ManualResetEventSlim();
|
var e = new ManualResetEventSlim();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
context.Post((_) =>
|
context.Post((_) =>
|
||||||
{
|
{
|
||||||
|
|
@ -766,7 +766,6 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[QuarantinedTest]
|
|
||||||
public async Task InvokeAsync_SyncWorkInAsyncTaskIsCompletedFirst()
|
public async Task InvokeAsync_SyncWorkInAsyncTaskIsCompletedFirst()
|
||||||
{
|
{
|
||||||
// Simplified version of ServerComponentRenderingTest.CanDispatchAsyncWorkToSyncContext
|
// Simplified version of ServerComponentRenderingTest.CanDispatchAsyncWorkToSyncContext
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@
|
||||||
"WebAssembly\\Server\\test\\Microsoft.AspNetCore.Components.WebAssembly.Server.Tests.csproj",
|
"WebAssembly\\Server\\test\\Microsoft.AspNetCore.Components.WebAssembly.Server.Tests.csproj",
|
||||||
"WebAssembly\\WebAssembly.Authentication\\src\\Microsoft.AspNetCore.Components.WebAssembly.Authentication.csproj",
|
"WebAssembly\\WebAssembly.Authentication\\src\\Microsoft.AspNetCore.Components.WebAssembly.Authentication.csproj",
|
||||||
"WebAssembly\\WebAssembly.Authentication\\test\\Microsoft.AspNetCore.Components.WebAssembly.Authentication.Tests.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\\src\\Microsoft.AspNetCore.Components.WebAssembly.csproj",
|
||||||
"WebAssembly\\WebAssembly\\test\\Microsoft.AspNetCore.Components.WebAssembly.Tests.csproj",
|
"WebAssembly\\WebAssembly\\test\\Microsoft.AspNetCore.Components.WebAssembly.Tests.csproj",
|
||||||
"WebAssembly\\testassets\\HostedInAspNet.Client\\HostedInAspNet.Client.csproj",
|
"WebAssembly\\testassets\\HostedInAspNet.Client\\HostedInAspNet.Client.csproj",
|
||||||
|
|
|
||||||
|
|
@ -21,26 +21,4 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)..\, Directory.Build.targets))\Directory.Build.targets" />
|
<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>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,8 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
|
||||||
_loggerFactory,
|
_loggerFactory,
|
||||||
_options,
|
_options,
|
||||||
client,
|
client,
|
||||||
_loggerFactory.CreateLogger<RemoteRenderer>());
|
_loggerFactory.CreateLogger<RemoteRenderer>(),
|
||||||
|
jsRuntime.ElementReferenceContext);
|
||||||
|
|
||||||
var circuitHandlers = scope.ServiceProvider.GetServices<CircuitHandler>()
|
var circuitHandlers = scope.ServiceProvider.GetServices<CircuitHandler>()
|
||||||
.OrderBy(h => h.Order)
|
.OrderBy(h => h.Order)
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,15 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
|
||||||
private readonly ILogger<RemoteJSRuntime> _logger;
|
private readonly ILogger<RemoteJSRuntime> _logger;
|
||||||
private CircuitClientProxy _clientProxy;
|
private CircuitClientProxy _clientProxy;
|
||||||
|
|
||||||
|
public ElementReferenceContext ElementReferenceContext { get; }
|
||||||
|
|
||||||
public RemoteJSRuntime(IOptions<CircuitOptions> options, ILogger<RemoteJSRuntime> logger)
|
public RemoteJSRuntime(IOptions<CircuitOptions> options, ILogger<RemoteJSRuntime> logger)
|
||||||
{
|
{
|
||||||
_options = options.Value;
|
_options = options.Value;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
DefaultAsyncTimeout = _options.JSInteropDefaultCallTimeout;
|
DefaultAsyncTimeout = _options.JSInteropDefaultCallTimeout;
|
||||||
JsonSerializerOptions.Converters.Add(new ElementReferenceJsonConverter());
|
ElementReferenceContext = new WebElementReferenceContext(this);
|
||||||
|
JsonSerializerOptions.Converters.Add(new ElementReferenceJsonConverter(ElementReferenceContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Initialize(CircuitClientProxy clientProxy)
|
internal void Initialize(CircuitClientProxy clientProxy)
|
||||||
|
|
|
||||||
|
|
@ -37,12 +37,15 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
|
||||||
ILoggerFactory loggerFactory,
|
ILoggerFactory loggerFactory,
|
||||||
CircuitOptions options,
|
CircuitOptions options,
|
||||||
CircuitClientProxy client,
|
CircuitClientProxy client,
|
||||||
ILogger logger)
|
ILogger logger,
|
||||||
|
ElementReferenceContext? elementReferenceContext)
|
||||||
: base(serviceProvider, loggerFactory)
|
: base(serviceProvider, loggerFactory)
|
||||||
{
|
{
|
||||||
_client = client;
|
_client = client;
|
||||||
_options = options;
|
_options = options;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
|
ElementReferenceContext = elementReferenceContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Dispatcher Dispatcher { get; } = Dispatcher.CreateDefault();
|
public override Dispatcher Dispatcher { get; } = Dispatcher.CreateDefault();
|
||||||
|
|
|
||||||
|
|
@ -258,7 +258,13 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
|
||||||
private class TestRemoteRenderer : RemoteRenderer
|
private class TestRemoteRenderer : RemoteRenderer
|
||||||
{
|
{
|
||||||
public TestRemoteRenderer(IServiceProvider serviceProvider, IClientProxy client)
|
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
|
private class TestRemoteRenderer : RemoteRenderer
|
||||||
{
|
{
|
||||||
public TestRemoteRenderer(IServiceProvider serviceProvider, ILoggerFactory loggerFactory, CircuitOptions options, CircuitClientProxy client, ILogger logger)
|
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,
|
NullLoggerFactory.Instance,
|
||||||
new CircuitOptions(),
|
new CircuitOptions(),
|
||||||
clientProxy,
|
clientProxy,
|
||||||
NullLogger.Instance);
|
NullLogger.Instance,
|
||||||
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
handlers = handlers ?? Array.Empty<CircuitHandler>();
|
handlers = handlers ?? Array.Empty<CircuitHandler>();
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,31 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// 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.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Components
|
namespace Microsoft.AspNetCore.Components
|
||||||
{
|
{
|
||||||
public class ElementReferenceJsonConverterTest
|
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]
|
[Fact]
|
||||||
public void Serializing_Works()
|
public void Serializing_Works()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var elementReference = ElementReference.CreateWithUniqueId();
|
var elementReference = ElementReference.CreateWithUniqueId(ElementReferenceContext);
|
||||||
var expected = $"{{\"__internalId\":\"{elementReference.Id}\"}}";
|
var expected = $"{{\"__internalId\":\"{elementReference.Id}\"}}";
|
||||||
var memoryStream = new MemoryStream();
|
var memoryStream = new MemoryStream();
|
||||||
var writer = new Utf8JsonWriter(memoryStream);
|
var writer = new Utf8JsonWriter(memoryStream);
|
||||||
|
|
@ -34,7 +43,7 @@ namespace Microsoft.AspNetCore.Components
|
||||||
public void Deserializing_Works()
|
public void Deserializing_Works()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var id = ElementReference.CreateWithUniqueId().Id;
|
var id = ElementReference.CreateWithUniqueId(ElementReferenceContext).Id;
|
||||||
var json = $"{{\"__internalId\":\"{id}\"}}";
|
var json = $"{{\"__internalId\":\"{id}\"}}";
|
||||||
var bytes = Encoding.UTF8.GetBytes(json);
|
var bytes = Encoding.UTF8.GetBytes(json);
|
||||||
var reader = new Utf8JsonReader(bytes);
|
var reader = new Utf8JsonReader(bytes);
|
||||||
|
|
@ -51,7 +60,7 @@ namespace Microsoft.AspNetCore.Components
|
||||||
public void Deserializing_WithFormatting_Works()
|
public void Deserializing_WithFormatting_Works()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var id = ElementReference.CreateWithUniqueId().Id;
|
var id = ElementReference.CreateWithUniqueId(ElementReferenceContext).Id;
|
||||||
var json =
|
var json =
|
||||||
@$"{{
|
@$"{{
|
||||||
""__internalId"": ""{id}""
|
""__internalId"": ""{id}""
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,13 @@ namespace Microsoft.AspNetCore.Components
|
||||||
{
|
{
|
||||||
private static readonly JsonEncodedText IdProperty = JsonEncodedText.Encode("__internalId");
|
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)
|
public override ElementReference Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
{
|
{
|
||||||
string id = null;
|
string id = null;
|
||||||
|
|
@ -39,7 +46,7 @@ namespace Microsoft.AspNetCore.Components
|
||||||
throw new JsonException("__internalId is required.");
|
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)
|
public override void Write(Utf8JsonWriter writer, ElementReference value, JsonSerializerOptions options)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// 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;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace WebAssembly.JSInterop
|
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);
|
public static extern string InvokeJSMarshalled(out string exception, ref long asyncHandle, string functionIdentifier, string argsJson);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[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 { resolveOptions, CircuitStartOptions } from './Platform/Circuits/CircuitStartOptions';
|
||||||
import { DefaultReconnectionHandler } from './Platform/Circuits/DefaultReconnectionHandler';
|
import { DefaultReconnectionHandler } from './Platform/Circuits/DefaultReconnectionHandler';
|
||||||
import { attachRootComponentToLogicalElement } from './Rendering/Renderer';
|
import { attachRootComponentToLogicalElement } from './Rendering/Renderer';
|
||||||
|
import { initializeProfiling } from './Platform/Profiling';
|
||||||
|
|
||||||
let renderingFailed = false;
|
let renderingFailed = false;
|
||||||
let started = false;
|
let started = false;
|
||||||
|
|
@ -21,6 +22,7 @@ async function boot(userOptions?: Partial<CircuitStartOptions>): Promise<void> {
|
||||||
throw new Error('Blazor has already started.');
|
throw new Error('Blazor has already started.');
|
||||||
}
|
}
|
||||||
started = true;
|
started = true;
|
||||||
|
initializeProfiling(null);
|
||||||
|
|
||||||
// Establish options to be used
|
// Establish options to be used
|
||||||
const options = resolveOptions(userOptions);
|
const options = resolveOptions(userOptions);
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import { WebAssemblyConfigLoader } from './Platform/WebAssemblyConfigLoader';
|
||||||
import { BootConfigResult } from './Platform/BootConfig';
|
import { BootConfigResult } from './Platform/BootConfig';
|
||||||
import { Pointer } from './Platform/Platform';
|
import { Pointer } from './Platform/Platform';
|
||||||
import { WebAssemblyStartOptions } from './Platform/WebAssemblyStartOptions';
|
import { WebAssemblyStartOptions } from './Platform/WebAssemblyStartOptions';
|
||||||
|
import { profileStart, profileEnd } from './Platform/Profiling';
|
||||||
|
|
||||||
let started = false;
|
let started = false;
|
||||||
|
|
||||||
|
|
@ -27,7 +28,9 @@ async function boot(options?: Partial<WebAssemblyStartOptions>): Promise<void> {
|
||||||
const platform = Environment.setPlatform(monoPlatform);
|
const platform = Environment.setPlatform(monoPlatform);
|
||||||
window['Blazor'].platform = platform;
|
window['Blazor'].platform = platform;
|
||||||
window['Blazor']._internal.renderBatch = (browserRendererId: number, batchAddress: Pointer) => {
|
window['Blazor']._internal.renderBatch = (browserRendererId: number, batchAddress: Pointer) => {
|
||||||
|
profileStart('renderBatch');
|
||||||
renderBatch(browserRendererId, new SharedMemoryRenderBatch(batchAddress));
|
renderBatch(browserRendererId, new SharedMemoryRenderBatch(batchAddress));
|
||||||
|
profileEnd('renderBatch');
|
||||||
};
|
};
|
||||||
|
|
||||||
// Configure navigation via JS Interop
|
// 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 { navigateTo, internalFunctions as navigationManagerInternalFunctions } from './Services/NavigationManager';
|
||||||
import { attachRootComponentToElement } from './Rendering/Renderer';
|
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
|
// Make the following APIs available in global scope for invocation from JS
|
||||||
window['Blazor'] = {
|
window['Blazor'] = {
|
||||||
|
|
@ -8,5 +10,7 @@ window['Blazor'] = {
|
||||||
_internal: {
|
_internal: {
|
||||||
attachRootComponentToElement,
|
attachRootComponentToElement,
|
||||||
navigationManager: navigationManagerInternalFunctions,
|
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 { Platform, System_Array, Pointer, System_Object, System_String } from '../Platform';
|
||||||
import { loadTimezoneData } from './TimezoneDataFile';
|
import { loadTimezoneData } from './TimezoneDataFile';
|
||||||
import { WebAssemblyBootResourceType } from '../WebAssemblyStartOptions';
|
import { WebAssemblyBootResourceType } from '../WebAssemblyStartOptions';
|
||||||
|
import { initializeProfiling } from '../Profiling';
|
||||||
|
|
||||||
let mono_string_get_utf8: (managedString: System_String) => Pointer;
|
let mono_string_get_utf8: (managedString: System_String) => Pointer;
|
||||||
let mono_wasm_add_assembly: (name: string, heapAddress: number, length: number) => void;
|
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) {
|
start: function start(resourceLoader: WebAssemblyResourceLoader) {
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
attachDebuggerHotkey(resourceLoader);
|
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
|
// dotnet.js assumes the existence of this
|
||||||
window['Browser'] = {
|
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 { EventFieldInfo } from './EventFieldInfo';
|
||||||
import { dispatchEvent } from './RendererEventDispatcher';
|
import { dispatchEvent } from './RendererEventDispatcher';
|
||||||
import { attachToEventDelegator as attachNavigationManagerToEventDelegator } from '../Services/NavigationManager';
|
import { attachToEventDelegator as attachNavigationManagerToEventDelegator } from '../Services/NavigationManager';
|
||||||
|
import { profileEnd, profileStart } from '../Platform/Profiling';
|
||||||
const selectValuePropname = '_blazorSelectValue';
|
const selectValuePropname = '_blazorSelectValue';
|
||||||
const sharedTemplateElemForParsing = document.createElement('template');
|
const sharedTemplateElemForParsing = document.createElement('template');
|
||||||
const sharedSvgElemForParsing = document.createElementNS('http://www.w3.org/2000/svg', 'g');
|
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 {
|
public updateComponent(batch: RenderBatch, componentId: number, edits: ArrayBuilderSegment<RenderTreeEdit>, referenceFrames: ArrayValues<RenderTreeFrame>): void {
|
||||||
|
profileStart('updateComponent');
|
||||||
|
|
||||||
const element = this.childComponentLocations[componentId];
|
const element = this.childComponentLocations[componentId];
|
||||||
if (!element) {
|
if (!element) {
|
||||||
throw new Error(`No element is currently associated with component ${componentId}`);
|
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) {
|
if ((activeElementBefore instanceof HTMLElement) && ownerDocument && ownerDocument.activeElement !== activeElementBefore) {
|
||||||
activeElementBefore.focus();
|
activeElementBefore.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
profileEnd('updateComponent');
|
||||||
}
|
}
|
||||||
|
|
||||||
public disposeComponent(componentId: number) {
|
public disposeComponent(componentId: number) {
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,14 @@ namespace Microsoft.AspNetCore.Components
|
||||||
public string? Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
public string? Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||||
public string? ValueAttribute { [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
|
namespace Microsoft.AspNetCore.Components.Forms
|
||||||
{
|
{
|
||||||
|
|
@ -53,7 +61,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
||||||
protected TValue CurrentValue { get { throw null; } set { } }
|
protected TValue CurrentValue { get { throw null; } set { } }
|
||||||
protected string? CurrentValueAsString { 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.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]
|
[Microsoft.AspNetCore.Components.ParameterAttribute]
|
||||||
[System.Diagnostics.CodeAnalysis.MaybeNullAttribute]
|
[System.Diagnostics.CodeAnalysis.MaybeNullAttribute]
|
||||||
[System.Diagnostics.CodeAnalysis.AllowNullAttribute]
|
[System.Diagnostics.CodeAnalysis.AllowNullAttribute]
|
||||||
|
|
@ -63,7 +71,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
||||||
[Microsoft.AspNetCore.Components.ParameterAttribute]
|
[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 { } }
|
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 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; }
|
public override System.Threading.Tasks.Task SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters) { throw null; }
|
||||||
void System.IDisposable.Dispose() { }
|
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);
|
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]
|
[Microsoft.AspNetCore.Components.ParameterAttribute]
|
||||||
public string ParsingErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
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 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; }
|
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>
|
public partial class InputNumber<TValue> : Microsoft.AspNetCore.Components.Forms.InputBase<TValue>
|
||||||
|
|
@ -89,9 +97,34 @@ namespace Microsoft.AspNetCore.Components.Forms
|
||||||
[Microsoft.AspNetCore.Components.ParameterAttribute]
|
[Microsoft.AspNetCore.Components.ParameterAttribute]
|
||||||
public string ParsingErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
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 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; }
|
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 partial class InputSelect<TValue> : Microsoft.AspNetCore.Components.Forms.InputBase<TValue>
|
||||||
{
|
{
|
||||||
public InputSelect() { }
|
public InputSelect() { }
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,14 @@ namespace Microsoft.AspNetCore.Components
|
||||||
public string? Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
public string? Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
|
||||||
public string? ValueAttribute { [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
|
namespace Microsoft.AspNetCore.Components.Forms
|
||||||
{
|
{
|
||||||
|
|
@ -51,7 +59,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
||||||
protected TValue CurrentValue { get { throw null; } set { } }
|
protected TValue CurrentValue { get { throw null; } set { } }
|
||||||
protected string? CurrentValueAsString { 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.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]
|
[Microsoft.AspNetCore.Components.ParameterAttribute]
|
||||||
public TValue Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
public TValue Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
|
||||||
[Microsoft.AspNetCore.Components.ParameterAttribute]
|
[Microsoft.AspNetCore.Components.ParameterAttribute]
|
||||||
|
|
@ -88,6 +96,29 @@ namespace Microsoft.AspNetCore.Components.Forms
|
||||||
protected override string? FormatValueAsString(TValue value) { throw null; }
|
protected override string? FormatValueAsString(TValue value) { throw null; }
|
||||||
protected override bool TryParseValueFromString(string? value, out TValue result, out string? validationErrorMessage) { 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 partial class InputSelect<TValue> : Microsoft.AspNetCore.Components.Forms.InputBase<TValue>
|
||||||
{
|
{
|
||||||
public InputSelect() { }
|
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>
|
/// <summary>
|
||||||
/// Gets the <see cref="FieldIdentifier"/> for the bound value.
|
/// Gets the <see cref="FieldIdentifier"/> for the bound value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected FieldIdentifier FieldIdentifier { get; set; }
|
protected internal FieldIdentifier FieldIdentifier { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the current value of the input.
|
/// Gets or sets the current value of the input.
|
||||||
|
|
@ -142,7 +142,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="value">The value to format.</param>
|
/// <param name="value">The value to format.</param>
|
||||||
/// <returns>A string representation of the value.</returns>
|
/// <returns>A string representation of the value.</returns>
|
||||||
protected virtual string? FormatValueAsString(TValue value)
|
protected virtual string? FormatValueAsString([AllowNull] TValue value)
|
||||||
=> value?.ToString();
|
=> value?.ToString();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override string FormatValueAsString(TValue value)
|
protected override string FormatValueAsString([AllowNull] TValue value)
|
||||||
{
|
{
|
||||||
switch (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>
|
/// </summary>
|
||||||
/// <param name="value">The value to format.</param>
|
/// <param name="value">The value to format.</param>
|
||||||
/// <returns>A string representation of the value.</returns>
|
/// <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.
|
// Avoiding a cast to IFormattable to avoid boxing.
|
||||||
switch (value)
|
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.
|
// 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.
|
// 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.Diagnostics.CodeAnalysis;
|
||||||
using System.Globalization;
|
|
||||||
using Microsoft.AspNetCore.Components.Rendering;
|
using Microsoft.AspNetCore.Components.Rendering;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Components.Forms
|
namespace Microsoft.AspNetCore.Components.Forms
|
||||||
|
|
@ -13,8 +11,6 @@ namespace Microsoft.AspNetCore.Components.Forms
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class InputSelect<TValue> : InputBase<TValue>
|
public class InputSelect<TValue> : InputBase<TValue>
|
||||||
{
|
{
|
||||||
private static readonly Type? _nullableUnderlyingType = Nullable.GetUnderlyingType(typeof(TValue));
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the child content to be rendering inside the select element.
|
/// Gets or sets the child content to be rendering inside the select element.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -34,31 +30,6 @@ namespace Microsoft.AspNetCore.Components.Forms
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override bool TryParseValueFromString(string? value, [MaybeNull] out TValue result, [NotNullWhen(false)] out string? validationErrorMessage)
|
protected override bool TryParseValueFromString(string? value, [MaybeNull] out TValue result, [NotNullWhen(false)] out string? validationErrorMessage)
|
||||||
{
|
=> this.TryParseSelectableValueFromString(value, out result, out 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)}'.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Components.Server.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
[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);
|
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)
|
private static TestInputSelect<TValue> FindInputSelectComponent<TValue>(CapturedBatch batch)
|
||||||
=> batch.ReferenceFrames
|
=> batch.ReferenceFrames
|
||||||
.Where(f => f.FrameType == RenderTreeFrameType.Component)
|
.Where(f => f.FrameType == RenderTreeFrameType.Component)
|
||||||
|
|
@ -117,6 +199,14 @@ namespace Microsoft.AspNetCore.Components.Forms
|
||||||
public TestEnum NotNullableEnum { get; set; }
|
public TestEnum NotNullableEnum { get; set; }
|
||||||
|
|
||||||
public TestEnum? NullableEnum { 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>
|
class TestInputSelect<TValue> : InputSelect<TValue>
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="$(ComponentsSharedSourceRoot)src\WebAssemblyJSInteropInternalCalls.cs" />
|
||||||
<Reference Include="Microsoft.JSInterop" />
|
<Reference Include="Microsoft.JSInterop" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -188,7 +188,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Authentication
|
||||||
var parameters = ParameterView.FromDictionary(new Dictionary<string, object>
|
var parameters = ParameterView.FromDictionary(new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
[_action] = RemoteAuthenticationActions.LogInCallback,
|
[_action] = RemoteAuthenticationActions.LogInCallback,
|
||||||
[_onLogInSucceded] = new EventCallbackFactory().Create< RemoteAuthenticationState>(
|
[_onLogInSucceded] = new EventCallbackFactory().Create<RemoteAuthenticationState>(
|
||||||
remoteAuthenticator,
|
remoteAuthenticator,
|
||||||
(state) => loggingSucceededCalled = true),
|
(state) => loggingSucceededCalled = true),
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,6 @@
|
||||||
Private="false"
|
Private="false"
|
||||||
Condition="'$(BuildNodeJS)' != 'false' and '$(BuildingInsideVisualStudio)' != 'true'" />
|
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" />
|
<SuppressBaselineReference Include="Microsoft.AspNetCore.Components.WebAssembly.HttpHandler" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Rendering
|
||||||
// The WebAssembly renderer registers and unregisters itself with the static registry
|
// The WebAssembly renderer registers and unregisters itself with the static registry
|
||||||
_webAssemblyRendererId = RendererRegistry.Add(this);
|
_webAssemblyRendererId = RendererRegistry.Add(this);
|
||||||
_logger = loggerFactory.CreateLogger<WebAssemblyRenderer>();
|
_logger = loggerFactory.CreateLogger<WebAssemblyRenderer>();
|
||||||
|
|
||||||
|
ElementReferenceContext = DefaultWebAssemblyJSRuntime.Instance.ElementReferenceContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Dispatcher Dispatcher => NullDispatcher.Instance;
|
public override Dispatcher Dispatcher => NullDispatcher.Instance;
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,12 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Services
|
||||||
{
|
{
|
||||||
internal static readonly DefaultWebAssemblyJSRuntime Instance = new DefaultWebAssemblyJSRuntime();
|
internal static readonly DefaultWebAssemblyJSRuntime Instance = new DefaultWebAssemblyJSRuntime();
|
||||||
|
|
||||||
|
public ElementReferenceContext ElementReferenceContext { get; }
|
||||||
|
|
||||||
private DefaultWebAssemblyJSRuntime()
|
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)
|
#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 System;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Blazor.Rendering
|
namespace Microsoft.AspNetCore.Components.WebAssembly.Rendering
|
||||||
{
|
{
|
||||||
public class RenderRegistryTest
|
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>
|
<TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
|
||||||
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
|
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
|
||||||
<UseBlazorWebAssembly>true</UseBlazorWebAssembly>
|
<UseBlazorWebAssembly>true</UseBlazorWebAssembly>
|
||||||
|
|
||||||
<FixupWebAssemblyHttpHandlerReference>true</FixupWebAssemblyHttpHandlerReference>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,6 @@
|
||||||
<TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
|
<TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
|
||||||
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
|
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
|
||||||
<UseBlazorWebAssembly>true</UseBlazorWebAssembly>
|
<UseBlazorWebAssembly>true</UseBlazorWebAssembly>
|
||||||
|
|
||||||
<FixupWebAssemblyHttpHandlerReference>true</FixupWebAssemblyHttpHandlerReference>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -40,13 +40,12 @@ namespace Wasm.Performance.Driver
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stressRunSeconds < 1)
|
if (stressRunSeconds < 0)
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine("Stress run duration must be a positive integer.");
|
Console.Error.WriteLine("Stress run duration must be a positive integer.");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
else if (stressRunSeconds > 0)
|
||||||
if (stressRunSeconds > 0)
|
|
||||||
{
|
{
|
||||||
isStressRun = true;
|
isStressRun = true;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,13 @@ namespace Wasm.Performance.Driver
|
||||||
{
|
{
|
||||||
const int SeleniumPort = 4444;
|
const int SeleniumPort = 4444;
|
||||||
static bool RunHeadlessBrowser = true;
|
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)
|
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. -->
|
<!-- WebDriver is not strong-named, so this test project cannot be strong named either. -->
|
||||||
<SignAssembly>false</SignAssembly>
|
<SignAssembly>false</SignAssembly>
|
||||||
<IsTestAssetProject>true</IsTestAssetProject>
|
<IsTestAssetProject>true</IsTestAssetProject>
|
||||||
|
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<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:
|
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 . `
|
2. `docker build -t blazor-local -f ./local.dockerfile . `
|
||||||
3. `docker run -it blazor-local`
|
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="renderlist">RenderList</a> |
|
||||||
<a href="json">JSON</a> |
|
<a href="json">JSON</a> |
|
||||||
<a href="orgchart">OrgChart</a> |
|
<a href="orgchart">OrgChart</a> |
|
||||||
<a href="timer">Timer</a>
|
<a href="timer">Timer</a> |
|
||||||
|
<a href="gridrendering">Grid</a>
|
||||||
|
|
||||||
<hr />
|
<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 './renderList.js';
|
||||||
import './jsonHandling.js';
|
import './jsonHandling.js';
|
||||||
import './orgChart.js';
|
import './orgChart.js';
|
||||||
|
import './grid.js';
|
||||||
import { getBlazorDownloadSize } from './blazorDownloadSize.js';
|
import { getBlazorDownloadSize } from './blazorDownloadSize.js';
|
||||||
|
|
||||||
new HtmlUI('E2E Performance', '#display');
|
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 \
|
RUN git init \
|
||||||
&& git fetch https://github.com/aspnet/aspnetcore ${gitBranch} \
|
&& git fetch https://github.com/aspnet/aspnetcore ${gitBranch} \
|
||||||
&& git reset --hard FETCH_HEAD \
|
&& 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 ./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
|
RUN chmod +x /app/Wasm.Performance.Driver
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ FROM selenium/standalone-chrome:3.141.59-mercury as final
|
||||||
ENV StressRunDuration=0
|
ENV StressRunDuration=0
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY ./Driver/bin/Release/netcoreapp3.1/linux-x64/publish ./
|
COPY ./Driver/bin/Release/net5.0/linux-x64/publish ./
|
||||||
COPY ./exec.sh ./
|
COPY ./exec.sh ./
|
||||||
|
|
||||||
ENTRYPOINT [ "bash", "./exec.sh" ]
|
ENTRYPOINT [ "bash", "./exec.sh" ]
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ using BasicTestApp;
|
||||||
using BasicTestApp.HttpClientTest;
|
using BasicTestApp.HttpClientTest;
|
||||||
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures;
|
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures;
|
||||||
using Microsoft.AspNetCore.E2ETesting;
|
using Microsoft.AspNetCore.E2ETesting;
|
||||||
|
using Microsoft.AspNetCore.Testing;
|
||||||
using OpenQA.Selenium;
|
using OpenQA.Selenium;
|
||||||
using OpenQA.Selenium.Support.UI;
|
using OpenQA.Selenium.Support.UI;
|
||||||
using TestServer;
|
using TestServer;
|
||||||
|
|
@ -44,6 +45,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23366")]
|
||||||
public void CanSendAndReceiveBytes()
|
public void CanSendAndReceiveBytes()
|
||||||
{
|
{
|
||||||
IssueRequest("/subdir/api/data");
|
IssueRequest("/subdir/api/data");
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using BasicTestApp;
|
||||||
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure;
|
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure;
|
||||||
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures;
|
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures;
|
||||||
using Microsoft.AspNetCore.E2ETesting;
|
using Microsoft.AspNetCore.E2ETesting;
|
||||||
|
using Microsoft.AspNetCore.Testing;
|
||||||
using Moq;
|
using Moq;
|
||||||
using OpenQA.Selenium;
|
using OpenQA.Selenium;
|
||||||
using OpenQA.Selenium.Support.UI;
|
using OpenQA.Selenium.Support.UI;
|
||||||
|
|
@ -506,6 +507,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23596")]
|
||||||
public void CanBindTextboxNullableDouble()
|
public void CanBindTextboxNullableDouble()
|
||||||
{
|
{
|
||||||
var target = Browser.FindElement(By.Id("textbox-nullable-double"));
|
var target = Browser.FindElement(By.Id("textbox-nullable-double"));
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[QuarantinedTest]
|
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23366")]
|
||||||
public void CanRenderTextOnlyComponent()
|
public void CanRenderTextOnlyComponent()
|
||||||
{
|
{
|
||||||
var appElement = Browser.MountTestComponent<TextOnlyComponent>();
|
var appElement = Browser.MountTestComponent<TextOnlyComponent>();
|
||||||
|
|
@ -400,6 +400,26 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
||||||
Browser.Equal("Clicks: 2", () => inputElement.GetAttribute("value"));
|
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]
|
[Fact]
|
||||||
public void CanCaptureReferencesToDynamicallyAddedElements()
|
public void CanCaptureReferencesToDynamicallyAddedElements()
|
||||||
{
|
{
|
||||||
|
|
@ -464,6 +484,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
[QuarantinedTest]
|
||||||
public void CanRenderMarkupBlocks()
|
public void CanRenderMarkupBlocks()
|
||||||
{
|
{
|
||||||
var appElement = Browser.MountTestComponent<MarkupBlockComponent>();
|
var appElement = Browser.MountTestComponent<MarkupBlockComponent>();
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ using BasicTestApp;
|
||||||
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure;
|
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure;
|
||||||
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures;
|
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures;
|
||||||
using Microsoft.AspNetCore.E2ETesting;
|
using Microsoft.AspNetCore.E2ETesting;
|
||||||
|
using Microsoft.AspNetCore.Testing;
|
||||||
using OpenQA.Selenium;
|
using OpenQA.Selenium;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using Xunit.Abstractions;
|
using Xunit.Abstractions;
|
||||||
|
|
@ -50,6 +51,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23596")]
|
||||||
public void ShowsErrorNotification_OnError_Reload()
|
public void ShowsErrorNotification_OnError_Reload()
|
||||||
{
|
{
|
||||||
var causeErrorButton = Browser.Exists(By.Id("throw-simple-exception"));
|
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