FluentStatement 2.00 Codename Spring Cleaning (isn't it Summer!?)

by M. Alberti (xanatos(at)live.it)

  • What is FluentStatement?

    FluentStatement is a fluent library for C# and .NET that lets the user create Lambda Expression(s) through its fluent (2nd and last time this word is used) interface. These Lambda Expressions can contain statements. All the standard statements of C# are included ({...}, while {...}, do {...} while, for {...}, foreach {...}, if {...}, switch {...}, using {...}, try {...} catch {...} finally {...}, throw, lock {...}), plus a favourite of mine, the trylock {...}, and the quite-famous do {...} until statements. Also present are methods to do assignments in Lambda Expressions.

    As a free gift you get some extension Expressions (not in the C# Method Extension sense but in the Extension.NodeType == ExpressionType.Extension and Extension.CanReduce == true sense): while {...}, do {...} while, do {...} until, for {...}, foreach {...}, using {...}, lock {...}, trylock {...}. For these look at the ExpressionEx class (sorry, no examples nor unit tests.)

  • Why is this library useful?

    The C# 4.0 and 4.5 compilers support Lambda Expressions and Lambda Statements. Sadly only the first ones are compilable to Expression Trees and are manipulable at runtime. Lambda Expressions can't contain statements, can't assign values to fields, properties or local variables (directly through the use of the = operator or indirectly through the use of the ++, --, +=, -= ... operators) and have other limits (empty Lambda Expression can't be built directly, throws statement can't be used, ...) It's now few years that fluent programming is very very trendy. Fluent interfaces are normally based on the Lambda Expression support of the C# compiler. This library helps building more complex Lambda Expressions that can contain statements, and it's fluent, and it's easily expandable to include more "verbs."

  • What about a small code sample?

        var list = new List<int>() { 1, 2, 3, 4, 5 };
    
        Expression<Func<IEnumerable<int>, int>> sum = 
            enu => FluentStatement.Start(s => 
                s.Block(
                    new { sum = 0 }, 
                    q => s.ForEach(
                        enu, 
                        ele => s.Increase(q.sum, ele)
                    ).Return(q.sum)
                ).DefaultValue<int>()
            );
    
        sum = sum.Expand();
    
        Func<IEnumerable<int>, int> sum2 = sum.Compile();
        var total = sum2(list);
    Note that from version 2.0 you could even do something like this (without using the anonymous object):
                s.Block(
                    0, 
                    q => s.ForEach(
                        enu, 
                        ele => s.Increase(q, ele)
                    ).Return(q)
                )

    This code will generate a sum Expression (and a sum2 delegate to use it). It is equivalent to the IEnumerable<int>.Sum() extension method. The DefaultValue<int>() is necessary because all the "verbs" of FluentStatement return a Statement object. Only Value<T> and DefaultValue<T> return T, so they can be used to "close" expressions that must return a value. All the FluentStatement "sentences" start with a

        () => FluentStatement.Starts(s =>
    

    or, if they have parameters

        (par1, ...) => FluentStatement.Starts(s => 
    

    FluentStatement "sentences" that must return a value end with a

        .Value<T>(something)
    

    or a

        .DefaultValue<T>() 
    
  • Why are there so few operation + assignment "verbs"? Why no Multiply, Divide, Mod, ShiftLeft, ShiftRight, And, Or, Xor, ...?

    FluentStatement includes only the most common (operation + assignment) "verbs", Pre/Post Increment/Decrement (++/--), Increase and Decrease (+=/-= .) Other verbs can easily be added by the user.

  • What versions of .NET does it support?

    FluentStatement requires .NET 4.0. It has been tested with Mono 2.10.8.

  • What license is FluentStatement released under?

    FluentStatement is released under the MIT license. If you need something more liberal (a beerware license?) you can ask me.

  • What is included in the solution?

    The solution includes the projects:

    • FluentStatement, the main library

    • Sample, a small code sample that shows many "verbs"

    • Tests, the unit test that tests all the verbs and show how they can be used.

  • Where does the idea come from?

    The base idea (especially on the use of the anonymous objects) comes from a series of articles Mitsu wrote on his blog

  • Have you used unit testing?

    FluentStatement uses extensively unit testing. It uses xUnit (minimum version 1.9.0) xUnit must be installed in the folder C:\xUnit to use the Tests project. If your installation of xUnit is in a different folder, please modify in the Tests.csproj file the line <XUnitPath>C:\xUnit</XUnitPath>.

  • Why is your code so obsessively-compulsively tidy?

    FluentStatement (and its author) are proud users of StyleCop (minimum version 4.7). A clean code is a sign of respect for those who will use it. The projects included in the solution will try to use the MSBuild include file for StyleCop if present in the folder $(ProgramFiles)\MSBuild\StyleCop\v4.7 folder (where $(ProgramFiles) is normally C:\Program Files or C:\Program Files (x86) .) To install the MSBuild include file you have to check the MSBuild integration checkbox during the installation of StyleCop.

  • Why isn't the code commented?

    FluentStatement (and its author) are proud users of StyleCop. Sadly the author is too much lazy to document the code. This is a sign of disrespect for those who will use it, but the author isn't very worried :-) Fortunately for the author, there are settings in StyleCop to disable the checking of comments.

  • Why is your English so much poor?

    FluentStatement has been written by an author who speaks very well Italian, but not so well British English or American English (or any other English idiom.) This is unfortunate, perhaps even tragic :-)

  • Known bugs

    • Dynamic types aren't supported.

  • Release history:

    • 2012-07-30 Version 2.00 Codename: Spring Cleaning (isn't it Summer!?)

      Added an option for using Block and ForEach with a single variable, without building first an anonymous object. Fixed a bug with chaining extension "fluent" methods (methods declared in subclasses of the Visitor.)

      Breaking change: renamed many classes, removing the FluentStatement from their names.

    • 2012-07-17 Version 1.20 Codename: Two for One, only at FluentStatement

      Fixed the ForEach to accept non-IEnumerable<T> types. Added a test for the duck-typing. Added the do {...} until expression. Added extension Expressions for while {...}, do {...} while, do {...} until, for {...}, foreach {...}, using {...}, lock {...}, trylock {...}) usable without the FluentStatement syntax.

    • 2012-07-15 Version 1.11 Codename: If it walks like a duck (part 2)

      Fixed a small bug in the Using statement where ValueTypes weren't correctly disposed.

    • 2012-07-12 Version 1.10 Codename: If it walks like a duck

      Fixed the duck-typing of ForEach. Now it should be able to find the currect "visible" methods GetEnumerable() and MoveNext() and property Current.

    • 2012-07-09 Version 1.00 Codename: Let's hope it isn't the last

      First public release.

The README is finished. Now go playing with the library.

Last edited Jul 31, 2012 at 9:56 AM by xanatos, version 32