diff --git a/src/Microsoft.AspNetCore.Blazor/Components/ParameterCollection.cs b/src/Microsoft.AspNetCore.Blazor/Components/ParameterCollection.cs index 0a0c83cb83..ddfd18ffce 100644 --- a/src/Microsoft.AspNetCore.Blazor/Components/ParameterCollection.cs +++ b/src/Microsoft.AspNetCore.Blazor/Components/ParameterCollection.cs @@ -2,6 +2,7 @@ // 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 Microsoft.AspNetCore.Blazor.RenderTree; namespace Microsoft.AspNetCore.Blazor.Components @@ -41,6 +42,42 @@ namespace Microsoft.AspNetCore.Blazor.Components public ParameterEnumerator GetEnumerator() => new ParameterEnumerator(_frames, _ownerIndex); + /// + /// Gets the value of the parameter with the specified name. + /// + /// The type of the value. + /// The name of the parameter. + /// Receives the result, if any. + /// True if a matching parameter was found; false otherwise. + public bool TryGetValue(string parameterName, out T result) + { + foreach (var entry in this) + { + if (string.Equals(entry.Name, parameterName)) + { + result = (T)entry.Value; + return true; + } + } + + result = default; + return false; + } + + /// + /// Returns a dictionary populated with the contents of the . + /// + /// A dictionary populated with the contents of the . + public IReadOnlyDictionary ToDictionary() + { + var result = new Dictionary(); + foreach (var entry in this) + { + result[entry.Name] = entry.Value; + } + return result; + } + // It's internal because there isn't a known use case for user code comparing // ParameterCollection instances, and even if there was, it's unlikely it should // use these equality rules which are designed for their effect on rendering. diff --git a/test/Microsoft.AspNetCore.Blazor.Test/ParameterCollectionTest.cs b/test/Microsoft.AspNetCore.Blazor.Test/ParameterCollectionTest.cs index e405b1f0e2..415e8aab29 100644 --- a/test/Microsoft.AspNetCore.Blazor.Test/ParameterCollectionTest.cs +++ b/test/Microsoft.AspNetCore.Blazor.Test/ParameterCollectionTest.cs @@ -85,6 +85,88 @@ namespace Microsoft.AspNetCore.Blazor.Test AssertParameter("attribute 2", attribute2Value)); } + [Fact] + public void CanTryGetNonExistingValue() + { + // Arrange + var parameterCollection = new ParameterCollection(new[] + { + RenderTreeFrame.Element(0, "some element").WithElementSubtreeLength(2), + RenderTreeFrame.Attribute(1, "some other entry", new object()) + }, 0); + + // Act + var didFind = parameterCollection.TryGetValue("nonexisting entry", out var value); + + // Assert + Assert.False(didFind); + Assert.Null(value); + } + + [Fact] + public void CanTryGetExistingValueWithCorrectType() + { + // Arrange + var parameterCollection = new ParameterCollection(new[] + { + RenderTreeFrame.Element(0, "some element").WithElementSubtreeLength(2), + RenderTreeFrame.Attribute(1, "my entry", "hello") + }, 0); + + // Act + var didFind = parameterCollection.TryGetValue("my entry", out var value); + + // Assert + Assert.True(didFind); + Assert.Equal("hello", value); + } + + [Fact] + public void ThrowsIfTryGetExistingValueWithIncorrectType() + { + // Arrange + var parameterCollection = new ParameterCollection(new[] + { + RenderTreeFrame.Element(0, "some element").WithElementSubtreeLength(2), + RenderTreeFrame.Attribute(1, "my entry", "hello") + }, 0); + + // Act/Assert + Assert.Throws(() => + { + parameterCollection.TryGetValue("my entry", out var value); + }); + } + + [Fact] + public void CanConvertToReadOnlyDictionary() + { + // Arrange + var entry2Value = new object(); + var parameterCollection = new ParameterCollection(new[] + { + RenderTreeFrame.Element(0, "some element").WithElementSubtreeLength(3), + RenderTreeFrame.Attribute(0, "entry 1", "value 1"), + RenderTreeFrame.Attribute(0, "entry 2", entry2Value), + }, 0); + + // Act + IReadOnlyDictionary dict = parameterCollection.ToDictionary(); + + // Assert + Assert.Collection(dict, + entry => + { + Assert.Equal("entry 1", entry.Key); + Assert.Equal("value 1", entry.Value); + }, + entry => + { + Assert.Equal("entry 2", entry.Key); + Assert.Same(entry2Value, entry.Value); + }); + } + private Action AssertParameter(string expectedName, object expectedValue) { return parameter =>