.NET Feature Management Database extends Feature Management for retrieving feature definitions from various databases. It includes abstractions and default implementations to facilitate easy integration with your .NET applications.
Package Purposes
- FeatureManagement.Database.Abstractions
- Standard functionalities for managing feature flags across various databases
- FeatureManagement.Database.EntityFrameworkCore
- Common package for EF Core with base implementations
- FeatureManagement.Database.EntityFrameworkCore.SqlServer
- Integration with SQL Server database using EF Core
- FeatureManagement.Database.EntityFrameworkCore.PostgreSQL
- Integration with PostgreSQL database using EF Core
- FeatureManagement.Database.EntityFrameworkCore.Sqlite
- Integration with Sqlite database using EF Core
- FeatureManagement.Database.EntityFrameworkCore.MySql
- Integration with MySql database using EF Core
- FeatureManagement.Database.Dapper
- Integration with Dapper
- FeatureManagement.Database.MongoDB
- Integration with MongoDB
- FeatureManagement.Database.NHibernate
- Integration with NHibernate
- FeatureManagement.Database.CosmosDB
- Integration with Azure Cosmos DB
.NET Feature Management Database allows you to manage feature definitions stored in a database.
The built-in DatabaseFeatureDefinitionProvider
retrieves these definitions and converts them into FeatureDefinition
objects used by the feature management system.
This setup relies on an implementation of the IFeatureStore
interface to access the database.
Two primary entities are pre-configured for database feature management:
-
Feature: represents a feature with its associated settings. Each feature has a unique name, a requirement type, and a collection of settings that define how the feature is enabled or disabled.
-
FeatureSettings: contains the settings for a feature and these define the conditions under which a feature is enabled. The condition parameters are stored in JSON format and based on Feature Management built-in feature filter or contextual feature filter configuration, and can include custom feature filter configuration.
Suppose you want to define a feature that is enabled for 50% of the users. Here is an example of how you can define such a feature and its settings:
…
var newFeature = new Feature
{
Id = Guid.NewGuid(),
Name = "NewFeature",
RequirementType = RequirementType.Any,
Settings = new List<FeatureSettings>
{
new FeatureSettings
{
Id = Guid.NewGuid(),
FilterType = FeatureFilterType.Percentage,
Parameters = "{\"Value\":50}"
}
}
}
…
The IFeatureStore
interface is the core abstraction for retrieving feature data from a database.
Implement this interface to connect to your specific database (e.g., SQL Server, MongoDB, etc.).
public class MyFeatureStore : IFeatureStore
{
// Implementation to fetch feature definitions from your database
}
See built-in database implementations.
Database feature management relies on .NET Core dependency injection. You can register the necessary services with a single line of code:
services.AddDatabaseFeatureManagement<MyFeatureStore>();
Note
In the context of database solutions, the feature management services will be added as scoped services.
Important
To use database feature management, you need to register an implementation of IFeatureStore.
Enhance performance and reduce database load using WithCacheService
:
-
Default Options
services.AddDatabaseFeatureManagement<MyFeatureStore>() .WithCacheService();
By default, the inactive cache will be removed after 30 minutes.
-
Custom Configuration Action
services.AddDatabaseFeatureManagement<MyFeatureStore>() .WithCacheService(options => { options.SlidingExpiration = TimeSpan.FromMinutes(10); options.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1); });
-
IConfiguration
var cacheConfiguration = Configuration.GetSection(FeatureCacheOptions.Name); services.AddDatabaseFeatureManagement<MyFeatureStore>() .WithCacheService(cacheConfiguration);
And in your
appsettings.json
:{ "FeatureCacheOptions": { "AbsoluteExpirationRelativeToNow": "01:00:00", "SlidingExpiration": "00:30:00" } }
The cache keys have a prefix (FMDb_) defined in the options (FeatureCacheOptions.CachePrefix
). By default:
Single feature | All features | |
---|---|---|
Key | FMDb_MyFeature | FMDb_features |
Note that "features" can be overridden when configuring cache. So you can have "FMDb_your-custom-cache-key"
.
See the FeatureCacheOptions
class for more cache-related settings.
Warning
Cache does not auto-refresh when feature values update directly in the database. Handle cache invalidation appropriately.
The basic form of feature management is checking if a feature flag is enabled and then performing actions based on the result.
This is done through the IFeatureManager
's IsEnabledAsync
method.
…
IFeatureManager featureManager;
…
if (await featureManager.IsEnabledAsync("MyFeature"))
{
// Do something
}
See more here.
The database feature management library provides support in ASP.NET Core and MVC to enable common feature flag scenarios in web applications.
See more here.
For easy integration with Entity Framework Core, you can use the FeatureManagement.Database.EntityFrameworkCore
package.
This package provides:
- A default, extendable
FeatureManagementDbContext
with pre-configured entities for features and feature settings. - A default
FeatureStore
implementation of theIFeatureStore
interface, which can be extended as needed.
First, install the package:
dotnet add package FeatureManagement.Database.EntityFrameworkCore
Then configure the services with the database provider you want:
services.AddDatabaseFeatureManagement<FeatureStore>()
.ConfigureDbContext<FeatureManagementDbContext>(builder => ...);
Using EF Core, you can work with different database providers which provide an extension method to the services.AddDatabaseFeatureManagement<FeatureStore>()
:
Database Provider | Package | Extension method |
---|---|---|
SQL Server | FeatureManagement.Database.EntityFrameworkCore.SqlServer |
UseSqlServer<FeatureManagementDbContext>(...); |
PostgreSQL | FeatureManagement.Database.EntityFrameworkCore.PostgreSQL |
UseNpgsql<FeatureManagementDbContext>(...); |
Sqlite | FeatureManagement.Database.EntityFrameworkCore.Sqlite |
UseSqlite<FeatureManagementDbContext>(...); |
MySql | FeatureManagement.Database.EntityFrameworkCore.MySql |
UseMySql<FeatureManagementDbContext>(...); |
If you already have an existing DbContext and want to integrate it with EF Core, download the main package and then
you can inherit from FeatureManagementDbContext
, so update your registration accordingly using your database provider (e.g. SQL Server):
services.AddDbContext<MyDbContext>(builder => builder.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddDatabaseFeatureManagement<MyFeatureStore>();
Note
When using a custom DbContext, ensure that MyFeatureStore
also extends the default one to utilize the custom DbContext.
For easy integration with Dapper, you can use the FeatureManagement.Database.Dapper
package.
This package provides:
- A default
FeatureStore
implementation of theIFeatureStore
interface, which can be extended as needed. - A
IDbConnectionFactory
for creating database connections.
First, install the package:
dotnet add package FeatureManagement.Database.Dapper
Then implement IDbConnectionFactory
to create a connection string to connect to your database:
public class SqlServerConnectionFactory : IDbConnectionFactory
{
private readonly string _connectionString;
public SqlServerConnectionFactory(string connectionString)
{
_connectionString = connectionString;
}
public IDbConnection CreateConnection()
{
return new SqlConnection(_connectionString);
}
}
And configure the services:
services.AddDatabaseFeatureManagement<FeatureStore>()
.UseDapper(new SqlServerConnectionFactory("Your_SqlServer_ConnString"));
For easy integration with MongoDB, you can use the FeatureManagement.Database.MongoDB
package.
This package provides:
- A default
FeatureStore
implementation of theIFeatureStore
interface, which can be extended as needed. - A
IMongoDBConnectionFactory
for creating database connections with default implementation.
First, install the package:
dotnet add package FeatureManagement.Database.MongoDB
Then use the default MongoDBConnectionFactory
or implement IMongoDBConnectionFactory
to create a custom connection string to connect to your database,
and configure the services:
services.AddDatabaseFeatureManagement<FeatureStore>()
.UseMongoDB(...);
For easy integration with NHibernate, you can use the FeatureManagement.Database.NHibernate
package.
This package provides:
- A default
FeatureStore
implementation of theIFeatureStore
interface, which can be extended as needed. - An
INHibernateConnectionFactory
for creating session factories with default implementation.
First, install the package:
dotnet add package FeatureManagement.Database.NHibernate
Then, use the default NHibernateConnectionFactory
or implement INHibernateConnectionFactory
to create a custom session factory, and configure the services:
services.AddDatabaseFeatureManagement<FeatureStore>()
.UseNHibernate(options =>
{
options.DatabaseConfigurer = /* Your database configurer, e.g., MsSqlConfiguration.MsSql2012.ConnectionString("your-connection-string") */;
options.ConfigureMapping = m => m.FluentMappings.AddFromAssemblyOf<YourMappingClass>();
options.ConfigurationSetup = cfg => { /* Additional NHibernate configurations */ };
});
Note
You can also use the default implementation and customize it configuring options, like the example above.
For easy integration with Cosmos DB, you can use the FeatureManagement.Database.CosmosDB
package.
This package provides:
- A default
FeatureStore
implementation of theIFeatureStore
interface, which can be extended as needed. - An
ICosmosDBConnectionFactory
for creating Cosmos DB clients with a default implementation.
First, install the package:
dotnet add package FeatureManagement.Database.CosmosDB
Then, use the default CosmosDBConnectionFactory
or implement ICosmosDBConnectionFactory
to create a custom Cosmos DB client, and configure the services:
services.AddDatabaseFeatureManagement<FeatureStore>()
.UseCosmosDB(options =>
{
options.EndpointUri = "https://your-cosmos-db-endpoint";
options.AccountKey = "your-cosmos-db-account-key";
options.DatabaseName = "your-database-name";
options.FeaturesCollectionName = "Features";
options.FeatureSettingsCollectionName = "FeatureSettings";
options.UseSeparateContainers = true; // or false if using a single container
});
Alternatively, you can configure the services using IConfiguration
:
services.AddDatabaseFeatureManagement<FeatureStore>()
.UseCosmosDB(Configuration.GetSection("CosmosDBOptions"));
You can also provide a custom ICosmosDBConnectionFactory
:
public class MyCustomCosmosDBConnectionFactory : ICosmosDBConnectionFactory
{
// Implement your own factory
}
...
services.AddDatabaseFeatureManagement<FeatureStore>()
.UseCosmosDB<MyCustomCosmosDBConnectionFactory>(options =>
{
...
});
Note
You can use the default implementation customizing it by configuring the options; otherwise override it or implement your own factory.
If you are using IConfiguration
, your appsettings.json might look like this:
{
"CosmosDBOptions": {
"EndpointUri": "https://your-cosmos-db-endpoint",
"AccountKey": "your-cosmos-db-account-key",
"DatabaseName": "your-database-name",
"FeaturesCollectionName": "Features",
"FeatureSettingsCollectionName": "FeatureSettings",
"UseSeparateContainers": true
}
}
Make sure to bind this section in your Startup.cs
or Program.cs
:
public void ConfigureServices(IServiceCollection services)
{
services.AddDatabaseFeatureManagement<FeatureStore>()
.UseCosmosDB(Configuration.GetSection("CosmosDBOptions"));
}
Please see Contribution Guidelines for more information.