2
\$\begingroup\$

Sometimes when designing a fluent-api it's important to build an object in a specific way/sequence.

I tried to create such a guided builder and came-up with this:

public class Query 
{
    public static IFrom Build() { return new Builder(); }

    public class Builder : IFrom, IWhere, ISelect, ICreate
    {
        public IWhere From() { return this; }
        public ISelect Where() { return this; }
        public ICreate Select() { return this; }

        public Query Create() { return new Query(); }
    }

    public interface IFrom { IWhere From(); }
    public interface IWhere { ISelect Where(); ICreate Select();  }
    public interface ISelect { ICreate Select(); }
    public interface ICreate { Query Create(); }
}

Usage:

var query1 = Query.Build().From().Where().Select().Create();

or

var query2 = Query.Build().From().Select().Create();

Without manual casting you are guided through the creation process so everything stays fluent. Or maybe there are better ways to suggest the fluent path?

\$\endgroup\$
  • \$\begingroup\$ @JanDotNet: Inspired by your replay to my other quesiton about creating immutable objects ;-) \$\endgroup\$ – t3chb0t Jun 27 '16 at 12:22
  • \$\begingroup\$ That reminds me quite a bit of LINQ. Why not writing your own Linq QueryProvider instead ;) \$\endgroup\$ – JanDotNet Jun 27 '16 at 12:36
  • \$\begingroup\$ What parameters do you plan to pass to the methods? Something like Query.Build().From("SELECT * from TABLE").Where("FieldA > 20").Select("Field3").Create(); ? \$\endgroup\$ – JanDotNet Jun 27 '16 at 12:58
  • \$\begingroup\$ @JanDotNet From/Where/Select might not have been the best example but it was the first thing I could think of right now where the order of operation matters ;-] anyways, an interesing article. It could be like in your example in the other answer where you need to specify all constructor parameters but without an order you could end it prematurely and skip some of them. \$\endgroup\$ – t3chb0t Jun 27 '16 at 12:59
  • \$\begingroup\$ @JanDotNet as a matter of fact I use such a linq-like syntax to load a configuration where I say From(this-data-source).Where(this-environment).Select(this-configuration) but currently it is possible to say just Select without specifying the other parameters. \$\endgroup\$ – t3chb0t Jun 27 '16 at 13:01
2
\$\begingroup\$

As written in the comment, it reminds me of LINQ. So, maybe it make sense to write a Linq QueryProvider to use the familiar LINQ syntax.

If that is not an option:

I would drop the method Build() and make the method From static instead. That simplifies the API.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.