Welcome to the OpenFeature .NET Workshop! This hands-on guide will take you through implementing feature flags using OpenFeature in a real-world .NET application.
Before starting, make sure you have:
- Completed the setup instructions in the README
- The application running via .NET Aspire
- Access to the Aspire Dashboard at https://localhost:15888
- Make sure the Docker containers are running
Each exercise builds upon the previous one, teaching you progressively more advanced OpenFeature concepts. Take your time with each exercise and don't hesitate to experiment!
Goal: Implement your first feature flag (without OpenFeature) and understand the basics
- How feature flags work in the application
- Basic boolean flag implementation
-
Explore the Current Implementation
- Navigate to
src/Garage.ServiceDefaults/Services/IFeatureFlags.cs - Review the
EnableStatsHeaderflag interface - Look at
FeatureFlags.csto see the environment variable implementation
- Navigate to
-
Toggle the Statistics Header
- Locate the environment variables in
src/Garage.AppHost/Properties/launchSettings.json - Change the
EnableStatsHeaderenvironment variable from"true"to"false" - Restart the application to see the behavior change in the web frontend
- Toggle it back to
"true"
- Locate the environment variables in
-
Verify the Changes
- Navigate to the web frontend
- Confirm the statistics header appears/disappears based on your flag value
-
Create a New Feature Flag
- Add a new boolean flag in
IFeatureFlags.cs(EnableTabs) making sure it istrue - Implement it in
FeatureFlags.csto read from environment variableEnableTabs - Add the environment variable to
launchSettings.jsonwith value"true" - Use this flag in the
.collection-tabsdiv in theHome.razorfile. Tip: You can use theShowHeaderflag as a reference
- Add a new boolean flag in
You should see the statistics header toggle on and off based on your feature flag value.
- Understand that feature flags are an application development practice that can be implemented basically (but as we'll see, can also become quite powerful and complex).
- Learn how environment variables can be used to configure feature flags at application startup.
Note: In this initial exercise, feature flags are configured using environment variables in the launchSettings.json file. Changes require an application restart. Later exercises will introduce dynamic flag updates through OpenFeature.
Goal: Use OpenFeature to manage feature flags dynamically and adding a custom provider
- How to integrate OpenFeature into a .NET application
- Implementing a custom feature flag provider
-
Install OpenFeature Dependencies
dotnet add src/Garage.ServiceDefaults package OpenFeature.Hosting
-
Configure OpenFeature in Extensions file
- Open
src/Garage.ServiceDefaults/Extensions.cs - Add OpenFeature services in the
AddFeatureFlagsmethod
- Open
-
Implement a Custom Provider
- Create a new class
CustomFeatureProviderinsrc/Garage.ServiceDefaults/Providers - Look at the
FeatureProviderbase class. Tip: You can try access the environment variables directly in theCustomFeatureProviderclass. Tip: You can skip implementing theResolveStructureValueAsyncmethod for now - Add the provider to the OpenFeature configuration in
Extensions.cs
- Create a new class
-
Replace the IFeatureFlags dependency injection
- Modify the usages of
IFeatureFlagsinterface to use OpenFeatureIFeatureClientinstead
- Modify the usages of
-
Make sure to use the UserId in the OpenFeature context
- Use the
_userIdproperty in theHome.razorfile to set the user context for OpenFeature - Ensure the OpenFeature client is aware of the user context. Tip: Have a look at the
EvaluationContextclass.
- Use the
You will have a basic OpenFeature integration that allows you to manage feature flags dynamically. You should see the custom provider in action, and the feature flags should be evaluated based on the user context.
- Understand that OpenFeature can be powered by any underlying "backend", as long as it can resolve feature flag values.
Goal: Integrate the flagd provider for feature flags
- How to use an external feature flag service
- Configuring OpenFeature with
flagd - Real-time flag updates without application restarts
-
Install the flagd Provider
dotnet add src/Garage.ServiceDefaults package OpenFeature.Contrib.Providers.Flagd
-
Configure the flagd Provider
- Open
src/Garage.ServiceDefaults/Extensions.cs - Add the
FlagdProviderto the OpenFeature configuration
- Open
-
Set Up flagd container
- Install the package
dotnet add src/Garage.AppHost package CommunityToolkit.Aspire.Hosting.Flagd
- Configure the
FlagdProviderwith the correct endpoint
var flagd = builder.AddFlagd("flagd", 8013) .WithBindFileSync("flags/");
-
Configure the flagd dependents
- Open
src/Garage.AppHost/Program.cs - Modify the
apiserviceandwebfrontendservices to wait for theflagdservice
- Open
You will have integrated the flagd provider into your OpenFeature setup, allowing you to manage feature flags
dynamically using an external service. You should be able to modify flags in the flagd.json file and see the changes
reflected in real-time without restarting the application.
- Understand that flagd is an OpenFeature-compatible backend for feature flags
Goal: Use integer flags to control performance characteristics
- How integer flags can control performance
- Real-time impact of performance tuning
- Using flags to simulate different performance scenarios
-
Understand the SlowOperationDelay Flag
- Find where this delay is implemented in the API service
-
Experiment with Different Delays
- Locate the
SlowOperationDelayflag inflagd.json - Change the delay to different values:
0(no delay)500(fast)1000(default)2000(slow)5000(very slow)
- Add a new integer flag for
SlowOperationDelayinflagd.json. For example:10000(time to grab a coffee). Tip: This might break the application, so you can have a look into the aspire dashboard to see the error logs - Test each configuration and observe the impact
- Locate the
-
Monitor Performance Impact
- Compare response times with different delay values
- Note how this affects user experience
-
Implement a Dynamic Configuration
- Consider how you might change this value without redeploying
- Think about gradual rollout scenarios (e.g., 90% of users get faster performance)
- Look into https://flagd.dev/playground/ for the fractional rollout feature example
You'll understand how integer flags can control performance characteristics and see real-time impact on application behavior.
- Understand that feature flags can be used to control performance characteristics in real-time
- Understand that feature flags can have multiple types, including integers, strings, and booleans
Goal: Toggle between different data sources using feature flags
- Architectural impact of feature flags
- Safe data migration techniques
- Boolean flags for major system changes
-
Understand the Data Sources
- Examine the
EnableDatabaseWinnersflag - Look at
WinnersService.csto see how it switches between:- Database source (PostgreSQL)
- JSON file source (
winners.json)
- Examine the
-
Test Data Source Switching
- Start with
EnableDatabaseWinners = false(JSON source) - Remove the 2024 winner from the JSON file
- Change to
EnableDatabaseWinners = true(database source) - Compare the data between sources
- Start with
-
Understand the Migration Pattern
- Review how the service gracefully handles the switch
- Consider error handling scenarios
- Think about data consistency during transitions
You'll see how feature flags can safely control major architectural decisions and enable smooth data migrations.
- Understand that feature flags can be used to control major architectural decisions, such as data sources
- Understand that feature flags can be used in combination to create complex feature configurations
Goal: Implement A/B testing using feature flags
- How to create and manage A/B tests
- Using variant-based feature flags
-
Use the flag
EnableStatsHeader- Using the
EnableStatsHeaderflag, implement a simple A/B test - Use the
EvaluationContextto differentiate between users, making sure to use the_userIdproperty - Use the "Change User ID" button on the homepage to simulate different users by changing your user ID
- Observe how the tabs are displayed in the web application
- Using the
-
Create a new configuration in flagd for
EnableTabs- Add a new flag in
flagd.jsonforEnableTabs - Set it to
truefor some users andfalsefor others - Don't forget to refresh the browser to see the changes
- Add a new flag in
You will have implemented a basic A/B test using feature flags, allowing you to control which users see different variants of the application.
- Understand that feature flags can be used for A/B testing, allowing you to experiment with different user experiences
- Understand that feature flags can be used to control the behavior of the application based on user attributes
Goal: Integrate analytics and monitoring for feature flags
- Add telemetry for flag evaluations
- Visualize flag usage in the Aspire dashboard
- Visualize trace data for flag evaluations
-
Add Telemetry for Feature Flags
- Open
src/Garage.ServiceDefaults/Extensions.cs - Add telemetry hooks to log flag evaluations (
TraceEnricherHookandMetricsHook) - Ensure the OTEL is configured to capture these events
- Open
-
Visualize Flag Usage
- Open the Aspire dashboard
- Visit the
Tracessection - Look for traces related to feature flag evaluations
- Check the
Metricssection for flag usage statistics
You will have integrated telemetry for feature flags, allowing you to monitor their usage and performance in the Aspire dashboard.
- Understand that feature flags can be monitored and analyzed using hooks
- Understand that feature flags can be visualized in any OTEL compatible dashboard using telemetry data
- Implement user segmentation based on attributes
- Create time-based flag activation
- Build geographic targeting rules
- Implement custom hooks for feature flag evaluations
- Use hooks to log flag evaluation behavior (see https://openfeature.dev/docs/reference/concepts/hooks/)
- Add an event handler to listen to flag changes (see https://openfeature.dev/specification/sections/events)
Application won't start
- Ensure .NET 9.0 SDK is installed
- Check that all NuGet packages are restored
- Verify docker is running (if using external Redis)
Feature flags not updating
- Restart the application after changes
- Check the Aspire dashboard for service status
- Verify flag values in the configuration
Database errors
- Ensure PostgreSQL database is created
- Run database migrations if needed
- Check database connection settings
- Review the OpenFeature Documentation
- Review the flagd Documentation
- Check the .NET Aspire Documentation
- Ask questions during the workshop session
Congratulations! You've completed the OpenFeature .NET workshop. You should now understand:
✅ Basic feature flag implementation
✅ Performance tuning with feature flags
✅ Architectural decisions using flags
✅ OpenFeature provider integration
✅ Advanced targeting and evaluation
- Explore other OpenFeature providers (https://openfeature.dev/ecosystem)
- Implement feature flags in your own applications
- Join the OpenFeature community
- Share your experience and learnings