Skip to content

Commit e39ceb5

Browse files
committed
Track enabled features
1 parent 7ecd0c9 commit e39ceb5

File tree

9 files changed

+51
-10
lines changed

9 files changed

+51
-10
lines changed

src/NServiceBus.Core.Tests/Features/FeatureDefaultsTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ protected internal override void Setup(FeatureConfigurationContext context)
4242
public void Init()
4343
{
4444
settings = new SettingsHolder();
45+
settings.Set(new FeatureComponent.Settings(settings));
4546
featureFactory = new FakeFeatureFactory();
4647
featureSettings = new FeatureActivator(settings, featureFactory);
4748
}

src/NServiceBus.Core.Tests/Features/FeatureDependencyTests.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ static IEnumerable<FeatureCombinations> FeatureCombinationsForTests
5454
[TestCaseSource(nameof(FeatureCombinationsForTests))]
5555
public void Should_only_activate_features_if_dependencies_are_met(FeatureCombinations setup)
5656
{
57-
var featureSettings = new FeatureActivator(new SettingsHolder(), new FeatureFactory());
57+
var settings = new SettingsHolder();
58+
settings.Set(new FeatureComponent.Settings(settings));
59+
var featureSettings = new FeatureActivator(settings, new FeatureFactory());
5860
var dependingFeature = setup.DependingFeature;
5961
featureSettings.Add(dependingFeature);
6062
Array.ForEach(setup.AvailableFeatures, featureSettings.Add);
@@ -79,6 +81,7 @@ public void Should_activate_upstream_dependencies_first()
7981
};
8082

8183
var settings = new SettingsHolder();
84+
settings.Set(new FeatureComponent.Settings(settings));
8285
var featureSettings = new FeatureActivator(settings, new FeatureFactory());
8386

8487
featureSettings.Add(dependingFeature);
@@ -111,6 +114,7 @@ public void Should_activate_named_dependency_first()
111114
};
112115

113116
var settings = new SettingsHolder();
117+
settings.Set(new FeatureComponent.Settings(settings));
114118
var featureSettings = new FeatureActivator(settings, new FeatureFactory());
115119

116120
featureSettings.Add(dependingFeature);
@@ -142,6 +146,7 @@ public void Should_not_activate_feature_when_named_dependency_disabled()
142146
};
143147

144148
var settings = new SettingsHolder();
149+
settings.Set(new FeatureComponent.Settings(settings));
145150
var featureSettings = new FeatureActivator(settings, new FeatureFactory());
146151

147152
featureSettings.Add(dependingFeature);
@@ -179,6 +184,7 @@ public void Should_activate_all_upstream_dependencies_first()
179184
};
180185

181186
var settings = new SettingsHolder();
187+
settings.Set(new FeatureComponent.Settings(settings));
182188
var featureSettings = new FeatureActivator(settings, new FeatureFactory());
183189

184190
featureSettings.Add(dependingFeature);
@@ -222,6 +228,7 @@ public void Should_activate_all_upstream_dependencies_when_chain_deep()
222228
};
223229

224230
var settings = new SettingsHolder();
231+
settings.Set(new FeatureComponent.Settings(settings));
225232
var featureSettings = new FeatureActivator(settings, new FeatureFactory());
226233

227234
//the orders matter here to expose a bug
@@ -259,6 +266,7 @@ public void Should_throw_exception_when_dependency_cycle_is_found()
259266
};
260267

261268
var settings = new SettingsHolder();
269+
settings.Set(new FeatureComponent.Settings(settings));
262270
var featureSettings = new FeatureActivator(settings, new FeatureFactory());
263271

264272
featureSettings.Add(level1);

src/NServiceBus.Core.Tests/Features/FeatureDifferingOnlyByNamespaceTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public void Should_activate_upstream_dependencies_first()
2424
};
2525

2626
var settings = new SettingsHolder();
27+
settings.Set(new FeatureComponent.Settings(settings));
2728
var featureSettings = new FeatureActivator(settings, new FeatureFactory());
2829

2930
featureSettings.Add(dependingFeature);

src/NServiceBus.Core.Tests/Features/FeatureSettingsTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public class FeatureSettingsTests
1616
public void Init()
1717
{
1818
settings = new SettingsHolder();
19+
settings.Set(new FeatureComponent.Settings(settings));
1920
featureSettings = new FeatureActivator(settings, new FeatureFactory());
2021
}
2122

src/NServiceBus.Core.Tests/Features/FeatureStartupTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public class FeatureStartupTests
1616
public void Init()
1717
{
1818
settings = new SettingsHolder();
19+
settings.Set(new FeatureComponent.Settings(settings));
1920
feautureFactory = new FakeFeatureFactory();
2021
featureSettings = new FeatureActivator(settings, feautureFactory);
2122
}

src/NServiceBus.Core.Tests/Features/FeatureTests.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,11 @@ public void Should_be_allow_features_to_request_being_enabled_by_default()
2222
}
2323

2424

25-
public class MyFeature : TestFeature
26-
{
27-
}
25+
public class MyFeature : TestFeature;
2826

2927

3028
public class MyEnabledByDefaultFeature : TestFeature
3129
{
32-
public MyEnabledByDefaultFeature()
33-
{
34-
EnableByDefault();
35-
}
30+
public MyEnabledByDefaultFeature() => EnableByDefault();
3631
}
3732
}

src/NServiceBus.Core/EndpointConfiguration.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public EndpointConfiguration(string endpointName)
3131
Settings.SetDefault("Transactions.DefaultTimeout", TransactionManager.DefaultTimeout);
3232

3333
Settings.Set(new AssemblyScanningComponent.Configuration(Settings));
34+
Settings.Set(new FeatureComponent.Settings(Settings));
3435
Settings.Set(new HostingComponent.Settings(Settings));
3536
Settings.Set(new TransportSeam.Settings(Settings));
3637
Settings.Set(new RoutingComponent.Settings(Settings));

src/NServiceBus.Core/Features/FeatureComponent.cs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace NServiceBus;
44

55
using System;
6+
using System.Collections.Generic;
67
using System.Linq;
78
using System.Threading;
89
using System.Threading.Tasks;
@@ -13,9 +14,20 @@ class FeatureComponent(SettingsHolder settings)
1314
{
1415
public void RegisterFeatureEnabledStatusInSettings(HostingComponent.Configuration hostingConfiguration)
1516
{
17+
var featureSettings = settings.Get<Settings>();
18+
19+
// When scanning is enabled we might find some types multiple times so we need to de-dupe them.
20+
var featureTypes = new HashSet<Type>(featureSettings.Features);
21+
22+
// When scanning is disabled the available types might only contain explicitely added stuff.
1623
foreach (var type in hostingConfiguration.AvailableTypes.Where(IsFeature))
1724
{
18-
featureActivator.Add(type.Construct<Feature>());
25+
featureTypes.Add(type);
26+
}
27+
28+
foreach (var featureType in featureTypes)
29+
{
30+
featureActivator.Add(featureFactory.CreateFeature(featureType));
1931
}
2032
}
2133

@@ -32,5 +44,23 @@ public void Initialize(FeatureConfigurationContext featureConfigurationContext)
3244

3345
static bool IsFeature(Type type) => typeof(Feature).IsAssignableFrom(type);
3446

35-
readonly FeatureActivator featureActivator = new(settings, new FeatureFactory());
47+
static readonly FeatureFactory featureFactory = new();
48+
readonly FeatureActivator featureActivator = new(settings, featureFactory);
49+
50+
public class Settings
51+
{
52+
readonly SettingsHolder settings;
53+
54+
public Settings(SettingsHolder settings)
55+
{
56+
this.settings = settings;
57+
Features = [];
58+
}
59+
60+
public HashSet<Type> Features
61+
{
62+
get => settings.Get<HashSet<Type>>("NServiceBus.Features.Features");
63+
private init => settings.Set("NServiceBus.Features.Features", value);
64+
}
65+
}
3666
}

src/NServiceBus.Core/Features/SettingsExtensions.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ public static SettingsHolder EnableFeatureByDefault(this SettingsHolder settings
2727
{
2828
ArgumentNullException.ThrowIfNull(settings);
2929
ArgumentNullException.ThrowIfNull(featureType);
30+
31+
_ = settings.Get<FeatureComponent.Settings>().Features.Add(featureType);
3032
settings.SetDefault(featureType.FullName, FeatureState.Enabled);
3133
return settings;
3234
}
@@ -53,6 +55,7 @@ public static bool IsFeatureEnabled(this IReadOnlySettings settings, Type featur
5355

5456
internal static void EnableFeature(this SettingsHolder settings, Type featureType)
5557
{
58+
_ = settings.Get<FeatureComponent.Settings>().Features.Add(featureType);
5659
settings.Set(featureType.FullName, FeatureState.Enabled);
5760
}
5861

0 commit comments

Comments
 (0)