Feature composition
First we need an abstract class for other features and a helper Empty
property. ForEach
will us allow to get all features.
abstract class Feature
{
public static Feature Empty => new CompositeFeature();
public virtual void ForEach(Action<Feature> feature) { feature(this); }
}
Next we need some contrete features:
class PowerWindows : Feature { }
class InjectionA : Feature { }
To build a feature chain we need a composite feature that will store the chain and it will also enumerate it:
class CompositeFeature : Feature
{
private readonly Feature[] _features;
public CompositeFeature(params Feature[] feautures)
{
_features = feautures;
}
public override void ForEach(Action<Feature> feature)
{
foreach (var f in _features)
{
f.ForEach(feature);
}
}
}
With an extension like this we can easily build the chain:
static class FeatureComposition
{
public static Feature Add<TFeature>(this Feature feature) where TFeature : Feature, new()
{
return new CompositeFeature(feature, new TFeature());
}
}
Usage:
var feature = Feature.Empty
.Add<PowerWindows>()
.Add<InjectionA>();
feature.ForEach(x => /* do somehting with x */ );
It's a one big feature that is composed of many other features.
I've added the ForEach
so that we can get them all and do something later with each of them.
One of my favourite patterns ;-)