Skip to content

Commit 1a41231

Browse files
committed
feat!: Use same type for flag metadata and event metadata
The spec describes two types(flag metadata, and event metadata) that are functionally the same. This PR makes a breaking change to bring both of the types to use a generic ImmutableMetadata type. - Rename BaseMetadata to Immutable, make sealed class and implement a empty constructor Fixes: #234 Signed-off-by: Benjamin Evenson <[email protected]>
1 parent be7f273 commit 1a41231

7 files changed

+39
-54
lines changed

src/OpenFeature/Model/FlagEvaluationDetails.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public sealed class FlagEvaluationDetails<T>
4848
/// <summary>
4949
/// A structure which supports definition of arbitrary properties, with keys of type string, and values of type boolean, string, or number.
5050
/// </summary>
51-
public FlagMetadata FlagMetadata { get; }
51+
public ImmutableMetadata FlagMetadata { get; }
5252

5353
/// <summary>
5454
/// Initializes a new instance of the <see cref="FlagEvaluationDetails{T}"/> class.
@@ -61,7 +61,7 @@ public sealed class FlagEvaluationDetails<T>
6161
/// <param name="errorMessage">Error message</param>
6262
/// <param name="flagMetadata">Flag metadata</param>
6363
public FlagEvaluationDetails(string flagKey, T value, ErrorType errorType, string reason, string variant,
64-
string errorMessage = null, FlagMetadata flagMetadata = null)
64+
string errorMessage = null, ImmutableMetadata flagMetadata = null)
6565
{
6666
this.Value = value;
6767
this.FlagKey = flagKey;

src/OpenFeature/Model/FlagMetadata.cs

-28
This file was deleted.

src/OpenFeature/Model/BaseMetadata.cs src/OpenFeature/Model/ImmutableMetadata.cs

+21-7
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,27 @@
66
namespace OpenFeature.Model;
77

88
/// <summary>
9-
/// Represents the base class for metadata objects.
9+
/// Represents the a immutable metadata associated with a feature flags and events.
1010
/// </summary>
11-
public abstract class BaseMetadata
11+
/// <seealso href="https://github.com/open-feature/spec/blob/v0.7.0/specification/types.md#flag-metadata"/>
12+
/// <seealso href="https://github.com/open-feature/spec/blob/v0.7.0/specification/types.md#event-metadata"/>
13+
public sealed class ImmutableMetadata
1214
{
1315
private readonly ImmutableDictionary<string, object> _metadata;
1416

15-
internal BaseMetadata(Dictionary<string, object> metadata)
17+
/// <summary>
18+
/// Constructor for the <see cref="ImmutableMetadata"/> class.
19+
/// </summary>
20+
public ImmutableMetadata()
21+
{
22+
this._metadata = ImmutableDictionary<string, object>.Empty;
23+
}
24+
25+
/// <summary>
26+
/// Constructor for the <see cref="ImmutableMetadata"/> class.
27+
/// </summary>
28+
/// <param name="metadata">The dictionary containing the metadata.</param>
29+
public ImmutableMetadata(Dictionary<string, object> metadata)
1630
{
1731
this._metadata = metadata.ToImmutableDictionary();
1832
}
@@ -22,7 +36,7 @@ internal BaseMetadata(Dictionary<string, object> metadata)
2236
/// </summary>
2337
/// <param name="key">The key of the value to retrieve.</param>
2438
/// <returns>The boolean value associated with the key, or null if the key is not found.</returns>
25-
public virtual bool? GetBool(string key)
39+
public bool? GetBool(string key)
2640
{
2741
return this.GetValue<bool>(key);
2842
}
@@ -32,7 +46,7 @@ internal BaseMetadata(Dictionary<string, object> metadata)
3246
/// </summary>
3347
/// <param name="key">The key of the value to retrieve.</param>
3448
/// <returns>The integer value associated with the key, or null if the key is not found.</returns>
35-
public virtual int? GetInt(string key)
49+
public int? GetInt(string key)
3650
{
3751
return this.GetValue<int>(key);
3852
}
@@ -42,7 +56,7 @@ internal BaseMetadata(Dictionary<string, object> metadata)
4256
/// </summary>
4357
/// <param name="key">The key of the value to retrieve.</param>
4458
/// <returns>The double value associated with the key, or null if the key is not found.</returns>
45-
public virtual double? GetDouble(string key)
59+
public double? GetDouble(string key)
4660
{
4761
return this.GetValue<double>(key);
4862
}
@@ -52,7 +66,7 @@ internal BaseMetadata(Dictionary<string, object> metadata)
5266
/// </summary>
5367
/// <param name="key">The key of the value to retrieve.</param>
5468
/// <returns>The string value associated with the key, or null if the key is not found.</returns>
55-
public virtual string? GetString(string key)
69+
public string? GetString(string key)
5670
{
5771
var hasValue = this._metadata.TryGetValue(key, out var value);
5872
if (!hasValue)

src/OpenFeature/Model/ProviderEvents.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ public class ProviderEventPayload
3636
/// <summary>
3737
/// Metadata information for the event.
3838
/// </summary>
39-
// TODO: This needs to be changed to a EventMetadata object
40-
public Dictionary<string, object> EventMetadata { get; set; }
39+
public ImmutableMetadata EventMetadata { get; set; }
4140
}
4241
}

src/OpenFeature/Model/ResolutionDetails.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public sealed class ResolutionDetails<T>
4747
/// <summary>
4848
/// A structure which supports definition of arbitrary properties, with keys of type string, and values of type boolean, string, or number.
4949
/// </summary>
50-
public FlagMetadata FlagMetadata { get; }
50+
public ImmutableMetadata FlagMetadata { get; }
5151

5252
/// <summary>
5353
/// Initializes a new instance of the <see cref="ResolutionDetails{T}"/> class.
@@ -60,7 +60,7 @@ public sealed class ResolutionDetails<T>
6060
/// <param name="errorMessage">Error message</param>
6161
/// <param name="flagMetadata">Flag metadata</param>
6262
public ResolutionDetails(string flagKey, T value, ErrorType errorType = ErrorType.None, string reason = null,
63-
string variant = null, string errorMessage = null, FlagMetadata flagMetadata = null)
63+
string variant = null, string errorMessage = null, ImmutableMetadata flagMetadata = null)
6464
{
6565
this.Value = value;
6666
this.FlagKey = flagKey;

test/OpenFeature.Tests/FlagMetadataTest.cs

+12-12
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class FlagMetadataTest
1515
public void GetBool_Should_Return_Null_If_Key_Not_Found()
1616
{
1717
// Arrange
18-
var flagMetadata = new FlagMetadata();
18+
var flagMetadata = new ImmutableMetadata();
1919

2020
// Act
2121
var result = flagMetadata.GetBool("nonexistentKey");
@@ -37,7 +37,7 @@ public void GetBool_Should_Return_Value_If_Key_Found()
3737
"boolKey", true
3838
}
3939
};
40-
var flagMetadata = new FlagMetadata(metadata);
40+
var flagMetadata = new ImmutableMetadata(metadata);
4141

4242
// Act
4343
var result = flagMetadata.GetBool("boolKey");
@@ -58,7 +58,7 @@ public void GetBool_Should_Throw_Value_Is_Invalid()
5858
"wrongKey", "11a"
5959
}
6060
};
61-
var flagMetadata = new FlagMetadata(metadata);
61+
var flagMetadata = new ImmutableMetadata(metadata);
6262

6363
// Act
6464
var result = flagMetadata.GetBool("wrongKey");
@@ -73,7 +73,7 @@ public void GetBool_Should_Throw_Value_Is_Invalid()
7373
public void GetInt_Should_Return_Null_If_Key_Not_Found()
7474
{
7575
// Arrange
76-
var flagMetadata = new FlagMetadata();
76+
var flagMetadata = new ImmutableMetadata();
7777

7878
// Act
7979
var result = flagMetadata.GetInt("nonexistentKey");
@@ -95,7 +95,7 @@ public void GetInt_Should_Return_Value_If_Key_Found()
9595
"intKey", 1
9696
}
9797
};
98-
var flagMetadata = new FlagMetadata(metadata);
98+
var flagMetadata = new ImmutableMetadata(metadata);
9999

100100
// Act
101101
var result = flagMetadata.GetInt("intKey");
@@ -117,7 +117,7 @@ public void GetInt_Should_Throw_Value_Is_Invalid()
117117
"wrongKey", "11a"
118118
}
119119
};
120-
var flagMetadata = new FlagMetadata(metadata);
120+
var flagMetadata = new ImmutableMetadata(metadata);
121121

122122
// Act
123123
var result = flagMetadata.GetInt("wrongKey");
@@ -132,7 +132,7 @@ public void GetInt_Should_Throw_Value_Is_Invalid()
132132
public void GetDouble_Should_Return_Null_If_Key_Not_Found()
133133
{
134134
// Arrange
135-
var flagMetadata = new FlagMetadata();
135+
var flagMetadata = new ImmutableMetadata();
136136

137137
// Act
138138
var result = flagMetadata.GetDouble("nonexistentKey");
@@ -154,7 +154,7 @@ public void GetDouble_Should_Return_Value_If_Key_Found()
154154
"doubleKey", 1.2
155155
}
156156
};
157-
var flagMetadata = new FlagMetadata(metadata);
157+
var flagMetadata = new ImmutableMetadata(metadata);
158158

159159
// Act
160160
var result = flagMetadata.GetDouble("doubleKey");
@@ -176,7 +176,7 @@ public void GetDouble_Should_Throw_Value_Is_Invalid()
176176
"wrongKey", "11a"
177177
}
178178
};
179-
var flagMetadata = new FlagMetadata(metadata);
179+
var flagMetadata = new ImmutableMetadata(metadata);
180180

181181
// Act
182182
var result = flagMetadata.GetDouble("wrongKey");
@@ -191,7 +191,7 @@ public void GetDouble_Should_Throw_Value_Is_Invalid()
191191
public void GetString_Should_Return_Null_If_Key_Not_Found()
192192
{
193193
// Arrange
194-
var flagMetadata = new FlagMetadata();
194+
var flagMetadata = new ImmutableMetadata();
195195

196196
// Act
197197
var result = flagMetadata.GetString("nonexistentKey");
@@ -213,7 +213,7 @@ public void GetString_Should_Return_Value_If_Key_Found()
213213
"stringKey", "11"
214214
}
215215
};
216-
var flagMetadata = new FlagMetadata(metadata);
216+
var flagMetadata = new ImmutableMetadata(metadata);
217217

218218
// Act
219219
var result = flagMetadata.GetString("stringKey");
@@ -235,7 +235,7 @@ public void GetString_Should_Throw_Value_Is_Invalid()
235235
"wrongKey", new object()
236236
}
237237
};
238-
var flagMetadata = new FlagMetadata(metadata);
238+
var flagMetadata = new ImmutableMetadata(metadata);
239239

240240
// Act
241241
var result = flagMetadata.GetString("wrongKey");

test/OpenFeature.Tests/OpenFeatureEventTests.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public async Task Event_Executor_Should_Propagate_Events_ToGlobal_Handler()
2525

2626
eventExecutor.AddApiLevelHandler(ProviderEventTypes.ProviderConfigurationChanged, eventHandler);
2727

28-
var eventMetadata = new Dictionary<string, object> { { "foo", "bar" } };
28+
var eventMetadata = new ImmutableMetadata(new Dictionary<string, object> { { "foo", "bar" } });
2929
var myEvent = new Event
3030
{
3131
EventPayload = new ProviderEventPayload

0 commit comments

Comments
 (0)