-
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
-
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.