/FeatureSwitcher

FeatureSwitcher is little library for feature switches/toggles.

Primary LanguageC#OtherNOASSERTION

What is FeatureSwitcher?

FeatureSwitcher is little library build to support you when you want to introduce feature switches/toggles in your code.

If needed it provides multi tenancy support. more info

How to use it

Create a class that names your feature and mark it with the IFeature interface.

class Sample : IFeature {}

Ask whether Feature<Sample>.Is().Enabled or Feature<Sample>.Is().Disabled.

With an instance of your feature

var sample = new Sample();

Ask whether sample.Is().Enabled or sample.Is().Disabled.

The state of the feature is determined by applying the behavior function to the feature name retrived by applying the naming convention function to the type of the feature.

Behavior and naming convention

Provided naming conventions

  • Features.OfAnyType.NamedByTypeFullName
  • Features.OfAnyType.NamedByTypeName
  • Features.OfType<T>.NamedByTypeFullName
  • Features.OfType<T>.NamedByTypeName

You can define an own naming convention with a function assignable to the Feature.NamingConvention delegate.

Provided behaviors

  • Features.OfAnyType.Enabled
  • Features.OfAnyType.Disabled
  • Features.OfType<T>.Enabled
  • Features.OfType<T>.Disabled
  • AppConfig.IsEnabled (via FeatureSwitcher.Configuration plugin)

You can define an own behavior with a function assignable to the Feature.Behavior delegate.

Configuration

By default all features are disabled and named by fullname of the type. You can provide an own behavior or naming convention simply by pass it into the configuration.

Features.Are
	.ConfiguredBy.Custom(behavior).And
	.NamedBy.Custom(namingConvention);

Multi tenancy / context support

Sometimes e.g. in a multitenant application you have features which should be enabled or disabled dependant of a context e.g. tenant. The plugin FeatureSwitcher.Contexteer provides support for contexts by utilizing Contexteer.

Assuming you have a context class named BusinessBranch and an instance of it named businessBranch you can ask FeatureSwitcher if your feature is enabled or disabled

Feature<Sample>.Is().EnabledInContextOf(businessBranch)
Feature<Sample>.Is().DisabledInContextOf(businessBranch)

And for an instance of your feature

sample.Is().EnabledInContextOf(businessBranch)
sample.Is().DisabledInContextOf(businessBranch)

You can provide own behavior and naming convention for contexts also by passing it into the configuration.

In<BusinessBranch>.Contexts.FeaturesAre()
	.ConfiguredBy(behavior).And
	.NamedBy(namingConvention);

Third party plugins

Examples

Some examples of possible usage.

Please as well have a look on the demo project by emardini.

How to get it

NuGet package manager

There are three packages

  • FeatureSwitcher - needed to do all the magic
  • FeatureSwitcher.Configuration - needed to configure the magic by app.config
  • FeatureSwitcher.Contexteer - needed to add context magic

How to contribute code

  • Login in github (you need an account)
  • Fork the main repository from Github
  • Push your changes to your GitHub repository
  • Send a pull request

Versioning

Versioning follows the Semantic Versioning Specification.

Some arguments for feature toggles

Alternatives?

Why this library?

Before this library was born, the existed alternatives (nToggle, FeatureToggle and NFeature) was tested.

The API of the first two is toggle centric it meens you have to decide while you coding how a feature is later controlled in production ex. using date range or database entry. Although the API of the last one is feature centric a feature must be defined as enum value what makes it complex for configuration.

A new library with a better feature centric API is needed, the FeatureSwitcher is born.

Background infos about API design

Why is a feature not

  • a string like by nToggle
    This is really simple -> MagicString
  • an enum value like by NFeature
    All features are defined in one place. At the first look it is cool, you can find all features easily, but you can't easily modularize the code ex. provide new features as addins.
  • a class like by FeatureToggle
    Actually there is no notion of a feature only of a toggle in FeatureToggle. A concrete feature toggle is defined by inheritance of a particular base type what defines how the feature is controlled in the future. The flexibility of this decision is lost. In addition the requirement of inheritance prevents the application in existing class hierarchies.

Decision: A feature must implement a marker interface! IFeature
Actually, the API could get along without this marker interface, the only reason for the interface is that you can, if it will be necessary, identify all the features by reflection or IDE.

Decision: A static generic class! Feature<>
Somehow you have to get from the feature to the state of the switch controlling it. Syntactic sugar.

Mentions