Skip to content

Commit ee77da9

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 cdc1bee commit ee77da9

7 files changed

+39
-52
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

-26
This file was deleted.

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

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

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

14-
internal BaseMetadata(Dictionary<string, object> metadata)
16+
/// <summary>
17+
/// Constructor for the <see cref="ImmutableMetadata"/> class.
18+
/// </summary>
19+
public ImmutableMetadata()
20+
{
21+
this._metadata = ImmutableDictionary<string, object>.Empty;
22+
}
23+
24+
/// <summary>
25+
/// Constructor for the <see cref="ImmutableMetadata"/> class.
26+
/// </summary>
27+
/// <param name="metadata">The dictionary containing the metadata.</param>
28+
public ImmutableMetadata(Dictionary<string, object> metadata)
1529
{
1630
this._metadata = metadata.ToImmutableDictionary();
1731
}
@@ -21,7 +35,7 @@ internal BaseMetadata(Dictionary<string, object> metadata)
2135
/// </summary>
2236
/// <param name="key">The key of the value to retrieve.</param>
2337
/// <returns>The boolean value associated with the key, or null if the key is not found.</returns>
24-
public virtual bool? GetBool(string key)
38+
public bool? GetBool(string key)
2539
{
2640
return this.GetValue<bool>(key);
2741
}
@@ -31,7 +45,7 @@ internal BaseMetadata(Dictionary<string, object> metadata)
3145
/// </summary>
3246
/// <param name="key">The key of the value to retrieve.</param>
3347
/// <returns>The integer value associated with the key, or null if the key is not found.</returns>
34-
public virtual int? GetInt(string key)
48+
public int? GetInt(string key)
3549
{
3650
return this.GetValue<int>(key);
3751
}
@@ -41,7 +55,7 @@ internal BaseMetadata(Dictionary<string, object> metadata)
4155
/// </summary>
4256
/// <param name="key">The key of the value to retrieve.</param>
4357
/// <returns>The double value associated with the key, or null if the key is not found.</returns>
44-
public virtual double? GetDouble(string key)
58+
public double? GetDouble(string key)
4559
{
4660
return this.GetValue<double>(key);
4761
}
@@ -51,7 +65,7 @@ internal BaseMetadata(Dictionary<string, object> metadata)
5165
/// </summary>
5266
/// <param name="key">The key of the value to retrieve.</param>
5367
/// <returns>The string value associated with the key, or null if the key is not found.</returns>
54-
public virtual string? GetString(string key)
68+
public string? GetString(string key)
5569
{
5670
var hasValue = this._metadata.TryGetValue(key, out var value);
5771
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
@@ -14,7 +14,7 @@ public class FlagMetadataTest
1414
public void GetBool_Should_Return_Null_If_Key_Not_Found()
1515
{
1616
// Arrange
17-
var flagMetadata = new FlagMetadata();
17+
var flagMetadata = new ImmutableMetadata();
1818

1919
// Act
2020
var result = flagMetadata.GetBool("nonexistentKey");
@@ -36,7 +36,7 @@ public void GetBool_Should_Return_Value_If_Key_Found()
3636
"boolKey", true
3737
}
3838
};
39-
var flagMetadata = new FlagMetadata(metadata);
39+
var flagMetadata = new ImmutableMetadata(metadata);
4040

4141
// Act
4242
var result = flagMetadata.GetBool("boolKey");
@@ -57,7 +57,7 @@ public void GetBool_Should_Throw_Value_Is_Invalid()
5757
"wrongKey", "11a"
5858
}
5959
};
60-
var flagMetadata = new FlagMetadata(metadata);
60+
var flagMetadata = new ImmutableMetadata(metadata);
6161

6262
// Act
6363
var result = flagMetadata.GetBool("wrongKey");
@@ -72,7 +72,7 @@ public void GetBool_Should_Throw_Value_Is_Invalid()
7272
public void GetInt_Should_Return_Null_If_Key_Not_Found()
7373
{
7474
// Arrange
75-
var flagMetadata = new FlagMetadata();
75+
var flagMetadata = new ImmutableMetadata();
7676

7777
// Act
7878
var result = flagMetadata.GetInt("nonexistentKey");
@@ -94,7 +94,7 @@ public void GetInt_Should_Return_Value_If_Key_Found()
9494
"intKey", 1
9595
}
9696
};
97-
var flagMetadata = new FlagMetadata(metadata);
97+
var flagMetadata = new ImmutableMetadata(metadata);
9898

9999
// Act
100100
var result = flagMetadata.GetInt("intKey");
@@ -116,7 +116,7 @@ public void GetInt_Should_Throw_Value_Is_Invalid()
116116
"wrongKey", "11a"
117117
}
118118
};
119-
var flagMetadata = new FlagMetadata(metadata);
119+
var flagMetadata = new ImmutableMetadata(metadata);
120120

121121
// Act
122122
var result = flagMetadata.GetInt("wrongKey");
@@ -131,7 +131,7 @@ public void GetInt_Should_Throw_Value_Is_Invalid()
131131
public void GetDouble_Should_Return_Null_If_Key_Not_Found()
132132
{
133133
// Arrange
134-
var flagMetadata = new FlagMetadata();
134+
var flagMetadata = new ImmutableMetadata();
135135

136136
// Act
137137
var result = flagMetadata.GetDouble("nonexistentKey");
@@ -153,7 +153,7 @@ public void GetDouble_Should_Return_Value_If_Key_Found()
153153
"doubleKey", 1.2
154154
}
155155
};
156-
var flagMetadata = new FlagMetadata(metadata);
156+
var flagMetadata = new ImmutableMetadata(metadata);
157157

158158
// Act
159159
var result = flagMetadata.GetDouble("doubleKey");
@@ -175,7 +175,7 @@ public void GetDouble_Should_Throw_Value_Is_Invalid()
175175
"wrongKey", "11a"
176176
}
177177
};
178-
var flagMetadata = new FlagMetadata(metadata);
178+
var flagMetadata = new ImmutableMetadata(metadata);
179179

180180
// Act
181181
var result = flagMetadata.GetDouble("wrongKey");
@@ -190,7 +190,7 @@ public void GetDouble_Should_Throw_Value_Is_Invalid()
190190
public void GetString_Should_Return_Null_If_Key_Not_Found()
191191
{
192192
// Arrange
193-
var flagMetadata = new FlagMetadata();
193+
var flagMetadata = new ImmutableMetadata();
194194

195195
// Act
196196
var result = flagMetadata.GetString("nonexistentKey");
@@ -212,7 +212,7 @@ public void GetString_Should_Return_Value_If_Key_Found()
212212
"stringKey", "11"
213213
}
214214
};
215-
var flagMetadata = new FlagMetadata(metadata);
215+
var flagMetadata = new ImmutableMetadata(metadata);
216216

217217
// Act
218218
var result = flagMetadata.GetString("stringKey");
@@ -234,7 +234,7 @@ public void GetString_Should_Throw_Value_Is_Invalid()
234234
"wrongKey", new object()
235235
}
236236
};
237-
var flagMetadata = new FlagMetadata(metadata);
237+
var flagMetadata = new ImmutableMetadata(metadata);
238238

239239
// Act
240240
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)