Skip to content

Commit f364e63

Browse files
benjirotoddbaert
authored andcommitted
feat!: Use same type for flag metadata and event metadata (open-feature#241)
## This PR **BREAKING CHANGE**, merge with 2.0 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 ImmutableMetadata, make sealed class and implement a empty constructor ### Related Issues Fixes: open-feature#234 --------- Signed-off-by: Benjamin Evenson <[email protected]> Signed-off-by: Todd Baert <[email protected]> Co-authored-by: Todd Baert <[email protected]> Signed-off-by: Artyom Tonoyan <[email protected]>
1 parent 99aa754 commit f364e63

7 files changed

+93
-109
lines changed
+28-28
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,55 @@
11
using OpenFeature.Constant;
22

33
namespace OpenFeature.Model
4-
{
4+
{
55
/// <summary>
66
/// The contract returned to the caller that describes the result of the flag evaluation process.
77
/// </summary>
88
/// <typeparam name="T">Flag value type</typeparam>
99
/// <seealso href="https://github.com/open-feature/spec/blob/v0.7.0/specification/types.md#evaluation-details"/>
10-
public sealed class FlagEvaluationDetails<T>
11-
{
10+
public sealed class FlagEvaluationDetails<T>
11+
{
1212
/// <summary>
1313
/// Feature flag evaluated value
1414
/// </summary>
15-
public T Value { get; }
16-
15+
public T Value { get; }
16+
1717
/// <summary>
1818
/// Feature flag key
1919
/// </summary>
20-
public string FlagKey { get; }
21-
20+
public string FlagKey { get; }
21+
2222
/// <summary>
2323
/// Error that occurred during evaluation
2424
/// </summary>
25-
public ErrorType ErrorType { get; }
26-
25+
public ErrorType ErrorType { get; }
26+
2727
/// <summary>
2828
/// Message containing additional details about an error.
2929
/// <para>
3030
/// Will be <see langword="null" /> if there is no error or if the provider didn't provide any additional error
3131
/// details.
3232
/// </para>
3333
/// </summary>
34-
public string? ErrorMessage { get; }
35-
34+
public string? ErrorMessage { get; }
35+
3636
/// <summary>
3737
/// Describes the reason for the outcome of the evaluation process
3838
/// </summary>
39-
public string? Reason { get; }
40-
39+
public string? Reason { get; }
40+
4141
/// <summary>
4242
/// A variant is a semantic identifier for a value. This allows for referral to particular values without
4343
/// necessarily including the value itself, which may be quite prohibitively large or otherwise unsuitable
4444
/// in some cases.
4545
/// </summary>
46-
public string? Variant { get; }
47-
46+
public string? Variant { get; }
47+
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; }
52-
51+
public ImmutableMetadata? FlagMetadata { get; }
52+
5353
/// <summary>
5454
/// Initializes a new instance of the <see cref="FlagEvaluationDetails{T}"/> class.
5555
/// </summary>
@@ -60,16 +60,16 @@ public sealed class FlagEvaluationDetails<T>
6060
/// <param name="variant">Variant</param>
6161
/// <param name="errorMessage">Error message</param>
6262
/// <param name="flagMetadata">Flag metadata</param>
63-
public FlagEvaluationDetails(string flagKey, T value, ErrorType errorType, string? reason, string? variant,
64-
string? errorMessage = null, FlagMetadata? flagMetadata = null)
65-
{
66-
this.Value = value;
67-
this.FlagKey = flagKey;
68-
this.ErrorType = errorType;
69-
this.Reason = reason;
70-
this.Variant = variant;
71-
this.ErrorMessage = errorMessage;
72-
this.FlagMetadata = flagMetadata;
73-
}
63+
public FlagEvaluationDetails(string flagKey, T value, ErrorType errorType, string? reason, string? variant,
64+
string? errorMessage = null, ImmutableMetadata? flagMetadata = null)
65+
{
66+
this.Value = value;
67+
this.FlagKey = flagKey;
68+
this.ErrorType = errorType;
69+
this.Reason = reason;
70+
this.Variant = variant;
71+
this.ErrorMessage = errorMessage;
72+
this.FlagMetadata = flagMetadata;
73+
}
7474
}
7575
}

src/OpenFeature/Model/FlagMetadata.cs

-25
This file was deleted.

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

+22-7
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,31 @@
11
using System.Collections.Generic;
22
using System.Collections.Immutable;
33

4+
#nullable enable
45
namespace OpenFeature.Model;
56

67
/// <summary>
7-
/// Represents the base class for metadata objects.
8+
/// Represents immutable metadata associated with feature flags and events.
89
/// </summary>
9-
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
1013
{
1114
private readonly ImmutableDictionary<string, object> _metadata;
1215

13-
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)
1429
{
1530
this._metadata = metadata.ToImmutableDictionary();
1631
}
@@ -20,7 +35,7 @@ internal BaseMetadata(Dictionary<string, object> metadata)
2035
/// </summary>
2136
/// <param name="key">The key of the value to retrieve.</param>
2237
/// <returns>The boolean value associated with the key, or null if the key is not found.</returns>
23-
public virtual bool? GetBool(string key)
38+
public bool? GetBool(string key)
2439
{
2540
return this.GetValue<bool>(key);
2641
}
@@ -30,7 +45,7 @@ internal BaseMetadata(Dictionary<string, object> metadata)
3045
/// </summary>
3146
/// <param name="key">The key of the value to retrieve.</param>
3247
/// <returns>The integer value associated with the key, or null if the key is not found.</returns>
33-
public virtual int? GetInt(string key)
48+
public int? GetInt(string key)
3449
{
3550
return this.GetValue<int>(key);
3651
}
@@ -40,7 +55,7 @@ internal BaseMetadata(Dictionary<string, object> metadata)
4055
/// </summary>
4156
/// <param name="key">The key of the value to retrieve.</param>
4257
/// <returns>The double value associated with the key, or null if the key is not found.</returns>
43-
public virtual double? GetDouble(string key)
58+
public double? GetDouble(string key)
4459
{
4560
return this.GetValue<double>(key);
4661
}
@@ -50,7 +65,7 @@ internal BaseMetadata(Dictionary<string, object> metadata)
5065
/// </summary>
5166
/// <param name="key">The key of the value to retrieve.</param>
5267
/// <returns>The string value associated with the key, or null if the key is not found.</returns>
53-
public virtual string? GetString(string key)
68+
public string? GetString(string key)
5469
{
5570
var hasValue = this._metadata.TryGetValue(key, out var value);
5671
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
}
+28-28
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,54 @@
11
using OpenFeature.Constant;
22

33
namespace OpenFeature.Model
4-
{
4+
{
55
/// <summary>
66
/// Defines the contract that the <see cref="FeatureProvider"/> is required to return
77
/// Describes the details of the feature flag being evaluated
88
/// </summary>
99
/// <typeparam name="T">Flag value type</typeparam>
1010
/// <seealso href="https://github.com/open-feature/spec/blob/v0.7.0/specification/types.md#resolution-details"/>
11-
public sealed class ResolutionDetails<T>
12-
{
11+
public sealed class ResolutionDetails<T>
12+
{
1313
/// <summary>
1414
/// Feature flag evaluated value
1515
/// </summary>
16-
public T Value { get; }
17-
16+
public T Value { get; }
17+
1818
/// <summary>
1919
/// Feature flag key
2020
/// </summary>
21-
public string FlagKey { get; }
22-
21+
public string FlagKey { get; }
22+
2323
/// <summary>
2424
/// Error that occurred during evaluation
2525
/// <see cref="ErrorType"/>
2626
/// </summary>
27-
public ErrorType ErrorType { get; }
28-
27+
public ErrorType ErrorType { get; }
28+
2929
/// <summary>
3030
/// Message containing additional details about an error.
3131
/// </summary>
32-
public string? ErrorMessage { get; }
33-
32+
public string? ErrorMessage { get; }
33+
3434
/// <summary>
3535
/// Describes the reason for the outcome of the evaluation process
3636
/// <see cref="Reason"/>
3737
/// </summary>
38-
public string? Reason { get; }
39-
38+
public string? Reason { get; }
39+
4040
/// <summary>
4141
/// A variant is a semantic identifier for a value. This allows for referral to particular values without
4242
/// necessarily including the value itself, which may be quite prohibitively large or otherwise unsuitable
4343
/// in some cases.
4444
/// </summary>
45-
public string? Variant { get; }
46-
45+
public string? Variant { get; }
46+
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; }
51-
50+
public ImmutableMetadata? FlagMetadata { get; }
51+
5252
/// <summary>
5353
/// Initializes a new instance of the <see cref="ResolutionDetails{T}"/> class.
5454
/// </summary>
@@ -59,16 +59,16 @@ public sealed class ResolutionDetails<T>
5959
/// <param name="variant">Variant</param>
6060
/// <param name="errorMessage">Error message</param>
6161
/// <param name="flagMetadata">Flag metadata</param>
62-
public ResolutionDetails(string flagKey, T value, ErrorType errorType = ErrorType.None, string? reason = null,
63-
string? variant = null, string? errorMessage = null, FlagMetadata? flagMetadata = null)
64-
{
65-
this.Value = value;
66-
this.FlagKey = flagKey;
67-
this.ErrorType = errorType;
68-
this.Reason = reason;
69-
this.Variant = variant;
70-
this.ErrorMessage = errorMessage;
71-
this.FlagMetadata = flagMetadata;
72-
}
62+
public ResolutionDetails(string flagKey, T value, ErrorType errorType = ErrorType.None, string? reason = null,
63+
string? variant = null, string? errorMessage = null, ImmutableMetadata? flagMetadata = null)
64+
{
65+
this.Value = value;
66+
this.FlagKey = flagKey;
67+
this.ErrorType = errorType;
68+
this.Reason = reason;
69+
this.Variant = variant;
70+
this.ErrorMessage = errorMessage;
71+
this.FlagMetadata = flagMetadata;
72+
}
7373
}
7474
}

0 commit comments

Comments
 (0)