Skip to content

Commit

Permalink
Added IReadOnlyDictionary to HttpRequestOptions (#86983)
Browse files Browse the repository at this point in the history
* Added IReadOnlyDictionary to HttpRequestOptions

Closes #68149

* Added test for new methods

* Added negative scenario to HttpRequestOptionsTest

Co-authored-by: Stephen Toub <[email protected]>

---------

Co-authored-by: Stephen Toub <[email protected]>
  • Loading branch information
xrem and stephentoub authored Jun 21, 2023
1 parent eccc410 commit 19a088e
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 2 deletions.
8 changes: 7 additions & 1 deletion src/libraries/System.Net.Http/ref/System.Net.Http.cs
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,10 @@ public HttpRequestOptionsKey(string key) {}
public string Key { get { throw null; } }
}

public sealed class HttpRequestOptions : System.Collections.Generic.IDictionary<string, object?>
public sealed class HttpRequestOptions : System.Collections.Generic.IDictionary<string, object?>, System.Collections.Generic.IReadOnlyDictionary<string, object?>
{
bool System.Collections.Generic.IReadOnlyDictionary<string, object?>.ContainsKey(string key) { throw null; }
int System.Collections.Generic.IReadOnlyCollection<System.Collections.Generic.KeyValuePair<string, object?>>.Count { get { throw null; } }
void System.Collections.Generic.IDictionary<string, object?>.Add(string key, object? value) { throw null; }
System.Collections.Generic.ICollection<string> System.Collections.Generic.IDictionary<string, object?>.Keys { get { throw null; } }
System.Collections.Generic.ICollection<object?> System.Collections.Generic.IDictionary<string, object?>.Values { get { throw null; } }
Expand All @@ -297,6 +299,10 @@ public sealed class HttpRequestOptions : System.Collections.Generic.IDictionary<
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
public bool TryGetValue<TValue>(HttpRequestOptionsKey<TValue> key, [MaybeNullWhen(false)] out TValue value) { throw null; }
public void Set<TValue>(HttpRequestOptionsKey<TValue> key, TValue value) { throw null; }
bool System.Collections.Generic.IReadOnlyDictionary<string, object?>.TryGetValue(string key, out object? value) { throw null; }
object? System.Collections.Generic.IReadOnlyDictionary<string, object?>.this[string key] { get { throw null; } }
System.Collections.Generic.IEnumerable<string> System.Collections.Generic.IReadOnlyDictionary<string, object?>.Keys { get { throw null; } }
System.Collections.Generic.IEnumerable<object?> System.Collections.Generic.IReadOnlyDictionary<string, object?>.Values { get { throw null; } }
}

public partial class HttpResponseMessage : System.IDisposable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ namespace System.Net.Http
/// <summary>
/// Represents a collection of options for an HTTP request.
/// </summary>
public sealed class HttpRequestOptions : IDictionary<string, object?>
public sealed class HttpRequestOptions : IDictionary<string, object?>, IReadOnlyDictionary<string, object?>
{
private Dictionary<string, object?> Options { get; } = new Dictionary<string, object?>();
bool IReadOnlyDictionary<string, object?>.TryGetValue(string key, out object? value) => Options.TryGetValue(key, out value);
object? IReadOnlyDictionary<string, object?>.this[string key] => Options[key];
IEnumerable<string> IReadOnlyDictionary<string, object?>.Keys => Options.Keys;
IEnumerable<object?> IReadOnlyDictionary<string, object?>.Values => Options.Values;
object? IDictionary<string, object?>.this[string key]
{
get
Expand All @@ -38,7 +42,9 @@ public sealed class HttpRequestOptions : IDictionary<string, object?>
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => ((System.Collections.IEnumerable)Options).GetEnumerator();
bool IDictionary<string, object?>.Remove(string key) => Options.Remove(key);
bool ICollection<KeyValuePair<string, object?>>.Remove(KeyValuePair<string, object?> item) => ((IDictionary<string, object?>)Options).Remove(item);
bool IReadOnlyDictionary<string, object?>.ContainsKey(string key) => Options.ContainsKey(key);
bool IDictionary<string, object?>.TryGetValue(string key, out object? value) => Options.TryGetValue(key, out value);
int IReadOnlyCollection<KeyValuePair<string, object?>>.Count => Options.Count;

/// <summary>
/// Initializes a new instance of the HttpRequestOptions class.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using Xunit;

namespace System.Net.Http.Tests
{
public class HttpRequestOptionsTest
{
[Fact]
public void HttpRequestOptionsIReadOnlyDictionaryMethods_Should_WorkSameAsIDictionary()
{
const string ExpectedKey = "WebAssemblyEnableStreamingResponse";
const bool ExpectedValue = true;
const string UnexpectedKey = "hello";

var requestOptions = new HttpRequestOptions();
requestOptions.Set(new HttpRequestOptionsKey<bool>(ExpectedKey), ExpectedValue);

IReadOnlyDictionary<string, object?> readOnlyDictionary = requestOptions;
IDictionary<string, object?> dictionary = requestOptions;

Assert.Equal(1, readOnlyDictionary.Count);
Assert.Equal(1, dictionary.Count);

Assert.True(readOnlyDictionary.ContainsKey(ExpectedKey));
Assert.True(dictionary.ContainsKey(ExpectedKey));
Assert.False(readOnlyDictionary.ContainsKey(UnexpectedKey));
Assert.False(dictionary.ContainsKey(UnexpectedKey));

Assert.True(readOnlyDictionary.TryGetValue(ExpectedKey, out object? getValueFromReadOnlyDictionary));
Assert.True(dictionary.TryGetValue(ExpectedKey, out object? getValueFromDictionary));
Assert.Equal(ExpectedValue, getValueFromReadOnlyDictionary);
Assert.Equal(ExpectedValue, getValueFromDictionary);

Assert.Equal(ExpectedValue, readOnlyDictionary[ExpectedKey]);
Assert.Equal(ExpectedValue, dictionary[ExpectedKey]);
Assert.Throws<KeyNotFoundException>(() => readOnlyDictionary[UnexpectedKey]);
Assert.Throws<KeyNotFoundException>(() => dictionary[UnexpectedKey]);

Assert.Collection(readOnlyDictionary.Keys, item => Assert.Equal(ExpectedKey, item));
Assert.Collection(dictionary.Keys, item => Assert.Equal(ExpectedKey, item));

Assert.Collection(readOnlyDictionary.Values, item => Assert.Equal(ExpectedValue, item));
Assert.Collection(dictionary.Values, item => Assert.Equal(ExpectedValue, item));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@
<Compile Include="Headers\HttpHeadersTest.cs" />
<Compile Include="Headers\HttpHeaderValueCollectionTest.cs" />
<Compile Include="Headers\HttpRequestHeadersTest.cs" />
<Compile Include="Headers\HttpRequestOptionsTest.cs" />
<Compile Include="Headers\HttpResponseHeadersTest.cs" />
<Compile Include="Headers\Int32NumberHeaderParserTest.cs" />
<Compile Include="Headers\Int64NumberHeaderParserTest.cs" />
Expand Down

0 comments on commit 19a088e

Please sign in to comment.