This sample leverages the pipeline to optionally skip executing specific handlers. It injects a behavior into the pipeline before a handler is executed and checks a list of feature toggle functions to determine whether or not the handler should be executed. If the handler is skipped, a message is logged.
The handlers
There are two handlers in the sample. Only Handler2
will be executed because Handler1
does not meet the conditions of the feature toggle.
The behavior
The feature toggle behavior contains a list of functions that decide whether the handler should be executed or not. Each toggle function accepts a handler context that contains details about the message being handled and the handler about to be executed. If all of the toggle functions return true, the handler is executed. If any of the toggle functions return false, then the handler is skipped and a message is logged.
class FeatureToggleBehavior :
Behavior<IInvokeHandlerContext>
{
static ILog log = LogManager.GetLogger<FeatureToggleBehavior>();
IList<Func<IInvokeHandlerContext, bool>> toggles;
public FeatureToggleBehavior(IList<Func<IInvokeHandlerContext, bool>> toggles)
{
this.toggles = toggles;
}
public override async Task Invoke(IInvokeHandlerContext context, Func<Task> next)
{
if (toggles.All(toggle => toggle(context)))
{
await next();
}
else
{
log.InfoFormat("Feature toggle skipped execution of handler: {0}", context.MessageHandler.HandlerType, context.MessageHandler);
}
}
}
The feature
The feature toggle's feature creates the behavior and adds it to the pipeline.
class FeatureToggles : Feature
{
protected override void Setup(FeatureConfigurationContext context)
{
var settings = context.Settings.Get<FeatureToggleSettings>();
var behavior = new FeatureToggleBehavior(settings.Toggles);
context.Pipeline.Register(behavior, "Optionally skips handlers based on feature toggles");
}
}
The configuration extension
This method extends the endpoint configuration to enable the feature toggle's feature and add the feature toggle settings to the configuration. These settings are returned to the caller for additional tweaking. The settings are also extracted by the feature toggle's feature and used to construct the feature toggle behavior (see above).
public static class FeatureToggleConfigurationExtensions
{
public static FeatureToggleSettings EnableFeatureToggles(this EndpointConfiguration endpointConfiguration)
{
endpointConfiguration.EnableFeature<FeatureToggles>();
return endpointConfiguration.GetSettings().GetOrCreate<FeatureToggleSettings>();
}
}
The endpoint configuration
With all of these pieces in place, the endpoint configuration code can set up feature toggles. In this sample, only Handler2
meets the conditions set out by the feature toggle.
var toggles = endpointConfiguration.EnableFeatureToggles();
toggles.AddToggle(ctx => ctx.MessageHandler.HandlerType == typeof(Handler2));