1

I have created a fluent API which works as expected. Now I would like to enforce some rules to make sure everything is built correct:

1: First method called should be BuildTestPlan, nothing else should be listed in intellisense (==> now all is available --> Solved: see update)

2: After BuildTestPlan only AddTestSequence should be available (==> this is ok)

3: After AddTestSequence only AddTest should be available (==> this is ok)

4: After AddTest there should be 3 options available: AddTest ( ==> this is ok), AddTestSequence (==> here I'm stuck) and GetResult (==> this is ok)

Code:

public class FluentTestPlanBuilderWithRules : ITestPlanBuilder, ITestSequenceBuilder, ITestBuilder
{
    public ITestSequenceBuilder BuildTestPlan()
    {
        // Do stuff
        return this;
    }

    public ITestBuilder AddTestSequence()
    {
        // Do stuff
        return this;
    }

    public ITestBuilder AddTest()
    {
        // Do stuff
        return this;
    }

    public TestPlan GetResult()
    {
        // Return built TestPlan
    }
}

public interface ITestPlanBuilder
{
    ITestSequenceBuilder BuildTestPlan();
}

public interface ITestSequenceBuilder
{
    ITestBuilder AddTestSequence();
}

public interface ITestBuilder
{
    ITestBuilder AddTest();
    TestPlan GetResult();
}

Usage:

var builder = new EnforcedFluentTestPlanBuilder();
var o = builder.BuildTestPlan()
        .AddTestSequence()
        .AddTest()
        .AddTest()
        .AddTest()
        .AddTestSequence()
        .AddTest()
        .AddTest()
        .AddTestSequence()
        .AddTest()
        .GetResult();

I'm afraid there is no way to enforce nr 1 since they are all public methods. But is it possible to have AddTestSequence both after AddTest and after BuildTestPlan?

UPDATE: Found a solution for nr 1 here

Community
  • 1
  • 1
Koen
  • 2,501
  • 1
  • 32
  • 43
  • For issue #4, have ITestBuilder inherit from ITestSequenceBuilder. Would that work for what you want? – JaCraig Jan 08 '14 at 16:49
  • @JaCraig this will make `AddTestSequence` also available after `AddTestSequence`, which should not be possible. – Koen Jan 08 '14 at 17:01
  • In that case create another interface that inherits from ITestBuilder and ITestSequenceBuilder and return that from ITestBuilder's AddTest method instead. Fluent interfaces are basically just like doing a FSM with interfaces, you just need another state/interface. – JaCraig Jan 13 '14 at 20:17
  • @JaCraig Nice 1! Works like a charm. You should add this as an answer. – Koen Jan 14 '14 at 06:40

0 Answers0