Skip to content

Easily manage feature flags in .NET and ASP.NET Core apps using your database.

License

Notifications You must be signed in to change notification settings

teociaps/FeatureManagement.Database

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

.NET Database Feature Management

Build Status Test Status

.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.

Index

Packages

Package NuGet Version
FeatureManagement.Database.Abstractions NuGet Version
FeatureManagement.Database.EntityFrameworkCore NuGet Version
FeatureManagement.Database.EntityFrameworkCore.SqlServer NuGet Version
FeatureManagement.Database.EntityFrameworkCore.PostgreSQL NuGet Version
FeatureManagement.Database.EntityFrameworkCore.Sqlite NuGet Version
FeatureManagement.Database.EntityFrameworkCore.MySql NuGet Version
FeatureManagement.Database.Dapper NuGet Version
FeatureManagement.Database.MongoDB NuGet Version
FeatureManagement.Database.NHibernate NuGet Version
FeatureManagement.Database.CosmosDB NuGet Version

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

Getting Started

.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.

Entities

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.

Example

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}"
        }
    }
}
…

Feature Store

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.

Service Registration

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.

Configure Cache

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"
        }
    }

Advanced Cache Configuration

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.

Consumption

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.

ASP.NET Core Integration

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.

Built-In Database Providers

Entity Framework Core

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 the IFeatureStore interface, which can be extended as needed.

Usage

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.

Dapper

For easy integration with Dapper, you can use the FeatureManagement.Database.Dapper package. This package provides:

  • A default FeatureStore implementation of the IFeatureStore interface, which can be extended as needed.
  • A IDbConnectionFactory for creating database connections.

Usage

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"));

MongoDB

For easy integration with MongoDB, you can use the FeatureManagement.Database.MongoDB package. This package provides:

  • A default FeatureStore implementation of the IFeatureStore interface, which can be extended as needed.
  • A IMongoDBConnectionFactory for creating database connections with default implementation.

Usage

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(...);

NHibernate

For easy integration with NHibernate, you can use the FeatureManagement.Database.NHibernate package. This package provides:

  • A default FeatureStore implementation of the IFeatureStore interface, which can be extended as needed.
  • An INHibernateConnectionFactory for creating session factories with default implementation.

Usage

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.

Cosmos DB

For easy integration with Cosmos DB, you can use the FeatureManagement.Database.CosmosDB package. This package provides:

  • A default FeatureStore implementation of the IFeatureStore interface, which can be extended as needed.
  • An ICosmosDBConnectionFactory for creating Cosmos DB clients with a default implementation.

Usage

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.

Example Configuration Section

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"));
}

Contributing

Please see Contribution Guidelines for more information.