DesignByContract with Fluent Interfaces

I was reading through some blog posts and through a recent post, stumbled across this one from Bill McCafferty and took a look at the DesignByContract CodeProject article. This is just a simple utility class to pass in assertions and get an exception to be thrown with a message if the contract has been violated. I did this manually in my last project using repetitive code that got to be a pain. On a new project I definately wanted to use a utility to perform these checks for me. The DesignByContract sample would seem to fit the solution. It is working fine thus far, but I didn’t like how the method calls looked and thought it would be a prime candidate for some fluent interfaces.

Here is my shabby attempt at a DesignByContract class to perform checks with fluent interfaces. Now instead of this:

Check.Require(!string.IsNullOrEmpty(username), “username is required”);

we can have this:

// with strings
Check.Parameter(username).WithMessage(“username is required”).IsNotNullOrEmpty();

// with objects
Check.Parameter(someObject).WithMessage(“some object is required”).IsNotNull();

A little longer to type, but with ReSharper who really types out whole method names anymore =) Theres probably a better way to do it with generics but for the time being I just needed to make sure that parameters were not null. So all this class does is check for null/not null. In the near future I will add assertion checks in there as well. I haven’t had a need for that yet and why write unnecessary code!

You can get the DesignByContract.cs and tests from my Google Source code repository here:

http://schambers.googlecode.com/svn/FluentDBC/

If anyone has any additions please send me a patch and I will be happy to add it!

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Sean Chambers

I am a Senior software developer from Palm Coast, Florida. An advocate of Domain Driven Design, Behavior Driven Development, creator of FluentMigrator and community activist. I am married to my beautiful wife Erin and am the proud father of two wonderful children. I currently reside at ACI, a local insurance industry/mortgage software company that excels in creating solutions using Agile methodologies.
This entry was posted in general. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://devlicio.us/ Billy McCafferty

    Very nice…I’ll be switching over to your modification with no questions asked!

  • http://www.lostechies.com/blogs/sean_chambers Sean Chambers

    cool deal. its not as detailed as the DesignByContract code project one that you noted, but I like the fluent interface alot better.

    When I noticed I had to do:
    Check(!string.IsNotNullOrEmpty(somestring));

    it made me wince because of how I had to pass the assertion in and how it read when browsing through the code.

    Over the next week I will start adding to it any other types of assertions I need.

  • http://joeydotnet.com/blog joeyDotNet

    Very nice indeed Sean. I keep telling myself I gotta start using Billy’s DBC utility on my projects, but somehow keep putting it off. You’ve just given me another reason to start using it.

  • http://www.lostechies.com/blogs/sean_chambers Sean Chambers

    definately give it a shot joey. I did the same thing and put off using a DBC class the last two projects and regretting it halfway through the project doing the repetiive:
    if (someval == null)
    throw new ArgumentNullException(“someval”);

    after typing that out 50 or so times it starts to get old.

    This time around I wanted to make sure that I got off on the right foot =)

  • http://blog.joelowrance.com Joe

    It would be nice if there was a way to move these checks to attributes, just to keep the “real” code a little cleaner.

  • http://www.lostechies.com/blogs/sean_chambers Sean Chambers

    Joe,

    That’s a good idea I think. The Check calls do take up alot of unneeded space. If they were attributes then it would be easier to glance at the method and instantly understand what checks are applied to a specific method.

    We could also then have an enum to denote a before or after check.

    If anyone makes modifications to the class please let me know and I will commit it to the google code repository.

    I will probably do it myself when I get a chance. I just brought home my new baby boy so I probably won’t have alot of time in the next week.

  • http://www.lostechies.com/blogs/joe_ocampo/ Joe Ocampo

    Awesome Sean!

    I was wondering what you thought of this. And upfront I never marry my code I just date it, so I am always open to criticism.

    I am really into Soluble (Alt.Net translation “Grokable”) code. And I know this is highly subjective but what do you think of this?

    When I read you method, it just didn’t read well. Don’t get me wrong it was very sound I just wondered if I could make it more soluble so it would read better.
    Check.Parameter(testList).WithMessage(“testList cannot be null”).IsNotNull();

    So I converted it to this? Any thoughts?
    Validate.ThatParameter(TestList).IsNotNull.IfInValidMessageShouldRead(“testList cannot be null”);

    Let the flames begin!!! ;-)

  • http://joeydotnet.com/blog joeyDotNet

    [Sarcasm]
    Whats_wrong_with_you_Joe_that_is_just_ridiculous_i_cant_believe_you_suggested_that()
    {
    LOL();
    Joking = true;
    }

    So here is a ruby-influenced spin for ya…

    ValidatePresenceOf(parameter).With.ErrorMessageOf(“parameter must be supplied”);

    If only we had lambda’s and symbols this would look sooo much prettier… :P

  • Joe

    If only there was an email address anywhere on this site…

    I made 2 changes
    1) Added a “WhenTrimmed” method to the string class, to account for ” ”
    2) Added a “DefaultValueCheck” class using generics. Maybe not useful for anyone but me, but lots of times I need to check that Guids are not empty, ints are not zero, DateTimes have been sent.

  • http://blog.jasonmeridth.com Jason Meridth

    @Joe

    I help run this site.

    It looks like Sean has disabled the feature to be contacted.

    He is receiving emails when comments are added to his posts. Please be patient.

    He is a new father.

    Thanks

  • http://www.lostechies.com/blogs/sean_chambers Sean Chambers

    @Joe: Sorry about that. My email address is dkode8@gmail.com. If you want to send the class zipped to me and then I will create a patch and apply it to the repository with the changes that you made.

    @Joe Ocampo: I like how that reads. I do think “Validate” is alot more appropriate than “Check”.

    I know what you mean by more soluable code. Thats what got me thinking about this originally. Once I started playing with it. It was my first attempt at a fluent interface so I wasn’t really sure how to setup the static methods/ instance methods to be able to chain the calls together. The only thing I would probably change is the “IfInvalidMessageShouldRead” to “MessageWillRead”. My thinking behind this is that a message would only be returned if the validation failed, so I think IfInvalid is ambiguous. What do you guys think?

    I like where this is going though. I think this could become really useful to some people. Especially since it cuts down on runtime bugs in addition to unit testing. Where should we go from here with it?

  • Joe

    @Joe Ocampo (and everyone else)

    Just curious, and like you said, it’s highly subjective but do you think a fluent interface is better served by a common verb such as “Do” or “Execute” to denote the end of the method chaining? Or should the solubility/”reads like an English sentence” take precedence over that?

    @Jason – thanks. My comment was more of a “hey what the hell – none of these guys have email addresses?” than anything else, sorry if I seemed pushy.

  • http://www.lostechies.com/blogs/joe_ocampo/ Joe Ocampo

    @Joe

    Personally speaking I believe that in order for code to be soluble, it simply meets one simple criterion.

    ~By simply looking at the code syntax can you easily asses with minimal effort the implicit of explicit behavior of the code.

    The precedence of “Reads like English” or ending with a common verb is subjective to the context of the behavior.

    Laymen translation “…it depends” :-)

    Just keep it simple and readable. What ever makes sense do it. If you are practicing TDD it should be easy to refactor if you do you like how the code reads.

    my two cents…

  • http://www.lostechies.com/blogs/jason_meridth Jason Meridth

    @Joe
    No worries. When you click into someones blog, there is usually a contact link on the right. This will give you a form to fill out and it will directly email the blog owner.

    @ Sean
    Create post. Sorry for using your comments to clarify this.
    Fluent interfaces rock. Sticking with strong typing is great especially with ReSharper. When you rename something you dont have to chase strings.

  • http://www.lostechies.com/blogs/sean_chambers Sean Chambers

    @Jason

    what did you mean by “create post”?

  • http://www.lostechies.com/blogs/jason_meridth Jason Meridth

    Sorry, meant “Great post”.

  • http://www.lostechies.com/blogs/sean_chambers Sean Chambers

    ah, right on. Definately a good topic. Alot of people seem interested in something like this, not to steal the idea from the code project article or bill mccafferty, but I thought I could expand on it.

  • http://blog.ashmind.com Andrey Shchekin

    The first thing that I look at with parameter validation is perfomance — the validation is called one or more times for nearly each method.

    I used simple Argument.RequireNotNull (checks and throws exception) just because it is straightforward and fast. While it is not as agile as fluent one, this is the one place where I feel performance to be important.

  • http://www.lostechies.com/blogs/sean_chambers Sean Chambers

    Good point Andrey,

    Does anyone have any comments on sacrificing performance for solubility?

    I think that the performance loss here is negligent. I’m sure if I were to runa benchmark on the Validation class that the difference would be so small that I would prefer to have it readable and sacrifice the peformance then not.

    Something to think about though. Perhaps attributes would be a better choice to cut down on the calls and make the validations more readable? Although I would hate to sprinkle attributes for validation throughout my domain model.

  • Joe

    I’m with you Sean – I’ll bet the performance difference is negligible even over high numbers of iterations. Plus, I’m banging against back end systems that I can guarantee are more of a bottleneck than me chaining a few simple methods and constructors together. When it comes time to optimize, I would spend my time where I would get the most bang for the buck – database calls, web services, etc.

  • http://www.pksoftware.net/ Paul Kohler

    Nice, its actually also one of the better examples of a fluent interface! Fluent interface code is nicer to read than the “old style” (!) I think the “performance” cost would be far outweighed by the code readability and self-documentation advantages – obviously depends on your requirements etc…

  • http://www.lostechies.com/blogs/sean_chambers Sean Chambers

    I agree with you there Paul. I would opt for solubility over performance unless it is really an issue like Joe mentioned with database/webservice calls.

    I feel this can be made alot more fluent or perhaps have more dimensions added to it.

    For example I find a need to already opt for the Validation to throw a specialized exception instead of a generic ArgumentNullException. I will be adding some code to make this possible. Just still trying to figure out how to make this fluent with the existing interface.

  • jlockwood

    Hmmmm…

    @Sean
    I like it, I’ve been using something similar based on McCafferty’s stuff and I do so enjoy fluent interfaces. I did, however, like McCafferty’s Require, Ensure, etc. (personal preference I suppose…and since I’m working solo on my current project my preference rules! – in my little world at least)

    @Ocampo
    I think that you’ve made an improvement with
    Validate.ThatParameter(TestList).IsNotNull.IfInValidMessageShouldRead(“testList cannot be null”);

    Still reads a little strange…IfInValidMessageShouldRead

    I’ve got this somewhere in my current code base:
    Check.Require(waterMeter.IsTransient(), “New WaterMeters must be transient to include them in a bulk insert.”)
    I imagine this could read:
    Require.That(waterMeter).IsTransient().When(“including in a bulk insert”)
    And this would consequently generate a PostconditionException (or TraceAssert) with the message:
    “DomainEntity of type WaterMeter can not be transient when included in a bulk insert” – or something to that effect.

    I’m not throwing stones or anything, just some thoughts. I’ll probably play around with this myself if I have the time (to determine feasibility). I’ll try to make objects Require/Ensure for pre/post conditions while I’m at it I suppose.

  • jlockwood

    I threw something together and am somewhat satisfied. I had some conditions using GreaterThan and created a generics base for Ensure and Require. I couldn’t use ”When’ because VB.Net is retarded, so I had to use ‘Whenever’. I do like the way is reads though.

    The following test are passing, but I’ve got mixed feelings regarding the implementation (and please excuse the VB as well as code formatting):

    _
    _
    Public Sub Should_raise_exception_on_Ensuring_invalid_greater_than_using_Decimal_type()
    Dim firstAgeInYears, secondAgeInYears As Integer
    Dim ageDifference As Decimal

    firstAgeInYears = 10
    secondAgeInYears = 21

    ageDifference = firstAgeInYears – secondAgeInYears

    Ensure(Of Decimal).That(ageDifference).IsGreaterThan(0).Whenever(“calculating age differences”)
    End Sub

    _
    Public Sub Should_Ensure_valid_greater_than_using_Decimal_type()
    Dim firstAgeInYears, secondAgeInYears As Integer
    Dim ageDifference As Decimal
    firstAgeInYears = 21
    secondAgeInYears = 10

    ageDifference = firstAgeInYears – secondAgeInYears

    Ensure(Of Decimal).That(ageDifference).IsGreaterThan(-1).Whenever(“calculating age differences”)
    End Sub

    _
    _
    Public Sub Should_raise_exception_on_Ensuring_invalid_greater_than_using_Integer_type()
    Dim denominator As Integer = 0

    Require(Of Integer).That(denominator).IsGreaterThan(0).Whenever(“preparing to use denominator value”)
    End Sub

  • http://www.lostechies.com/blogs/joe_ocampo/ Joe Ocampo

    What is that strange language?????? LOL

  • http://www.lostechies.com/blogs/sean_chambers Sean Chambers

    I like it Josh. I think I am going to add the same syntax to the fluentdbc. I perticularly like the That(value) syntax. that’s very readable and conveys meaning. What is the difference between Require and Ensure?

    I feel we need a way here to pass a custom exception. For instance, on a piece of code I was working on yesterday I wanted to return an AccountAvailableException instead of ArgumentNullException when performing a check to see if an e-mail address is already taken in the system. Now, in hindsight I think this really needs to be part of the domain model instead of simple value checks but there may be other cases where something like this is needed. Perhaps adding on another method that reads like:

    Validate(value).IsGreaterThan(-1).WithMessage(“value is not a valid range”).Throw(typeof(SomeCustomException));

  • http://www.lostechies.com/blogs/joe_ocampo/ Joe Ocampo

    Caution when throwing exceptions in a fluent interface.

    While fluent interfaces may be more soluable it comes with a sacrifice of debugability. Take for instance your example. I went ahead a mocked it up quickly:

    [TestFixture]
    public class DBCSpecs
    {
    [Test]
    public void ShouldThrowException()
    {
    int myNumber = -2;
    Validate.That(myNumber).IsGreaterThan(-1).WithMessage(“value is not a valid range”).Throw(typeof(SomeCustomException));
    }
    }

    public class Validate
    {
    public static PredicateBranch That(int contextValue)
    {
    return new PredicateBranch(contextValue);
    }
    }

    public class PredicateBranch
    {
    private readonly int contexValue;

    public PredicateBranch(int contexValue)
    {
    this.contexValue = contexValue;
    }

    public MessageBranch IsGreaterThan(int conditionalValue)
    {
    return contexValue > conditionalValue ? new MessageBranch(false) : new MessageBranch(true);
    }
    }

    public class MessageBranch
    {
    private readonly bool showMessage;

    public MessageBranch(bool showMessage)
    {
    this.showMessage = showMessage;
    }

    public ExceptionBranch WithMessage(string invalidMessage)
    {
    return new ExceptionBranch(invalidMessage, showMessage);
    }
    }

    public class ExceptionBranch
    {
    private readonly string errorMessage;
    private readonly bool showMessage;

    public ExceptionBranch(string errorMessage, bool showMessage)
    {
    this.errorMessage = errorMessage;
    this.showMessage = showMessage;
    }

    public void Throw(Type type)
    {
    if(showMessage)
    {
    throw new SomeCustomException(errorMessage);
    }
    }
    }

    public class SomeCustomException : Exception
    {
    public SomeCustomException(string message) : base(message)
    {
    }
    }

    If I run this I will get the following stack trace.

    Stack: at MbUnitExample.ExceptionBranch.Throw(Type type) in C:\Projects\MbUnitExample\MbUnitExample\DBCSpecs.cs:line 72
    at MbUnitExample.DBCSpecs.ShouldThrowException() in C:\Projects\MbUnitExample\MbUnitExample\DBCSpecs.cs:line 15

    You will notice that the exception is being thrown by the ExceptionBranch class and not the enclosing method as would be expected. I know it is a small issue but one that can really get to be a pain if you aren’t careful.

    SideNote: I would encourage refactoring to Generics but I ran out of time. After all this is a comment!

  • http://blog.bits-in-motion.com/ Jeff Brown

    @schambers:
    Be careful. These DBC-ish shortcuts are not really a substitute for checks that result in ArgumentNullExceptions being thrown. As for typing the same pattern over and over I find copy-and-paste works well. When that fails R# custom templates are pretty good.

    Also, R# knows how to automatically rename the method parameter names that appear in places ike ArgumentNullException. So it’ll keep everything in sync nicely. Doesn’t seem to work when the check is moved to another function.

    Moreover, performing the check locally within the function may give the JIT more latitude to optimize the code it generates.

  • jlockwood

    @Sean
    “What is the difference between Require and Ensure?”
    This is base on McCafferty’s original approach on the matter. He supported calls such as Check.Require, Check.Ensure, etc. They each indicate the realationship of the check to the surrounding code and throw different exceptions accordingly.

    It’s the same here…
    Require is a precondition check. It’s used to specify a required state before carrying out an operation. In the aforementioned example I had:
    Require(Of Integer).That(denominator).IsGreaterThan(0).Whenever(“preparing to use denominator value”)
    …in one of my tests. Let’s say I used this in a method that takes several parameters to calculate some ratio that is important to the business…I might enforce the requirement that the value provided for the denominator not be zero BEFORE the calculation. If the Requirement fails, a PreconditionException is raised. This could also be done in a try catch so that a business-specific exception is propogated with the originating PreconditionException as an inner exception. This is a simple example but should illustrate the point.

    Ensure, on the other hand, would be used to ensure a specified state AFTER an operation is carried out. Again, in one of the aforementioned tests I used ensure to validate the difference between two ages AFTER the difference was calculated. It’s also a simple example and was only made to illustrate the point.

    In short, here were the kinds of checks that I first got from McCafferty’s code:
    Require: precondition check
    Ensure: postcondition check
    Invariant: check ensuring that state has not changed (useful for guarding against method side effects)
    Assert: general assertion with no operational context

    As you’ve probably noticed, each has a specific type of exception associated with it based on operational context. These would have to be caught and wrapped by a business-specific exception (which is why I don’t support custom exceptions). I may consider supporting a UsingMessage() or WhenFails() method that could be used in lieu of Whenever() to override generated messages, but Whenever() works in most cases from my stand point.

    Perhaps I could support both these syntaxes:
    Default:
    Ensure(Of Decimal).That(ageDifference).IsGreaterThan(0).Whenever(“calculating age differences”)
    Creates message:
    “Decimal object was not greater than 0 when calculating age differences”
    Throws exception:
    PostconditionException

    Alternate:
    Ensure(Of Decimal).That(ageDifference).IsGreaterThan(0).AndShow(“ageDifference must be greater than zero”).Whenever(“calculating age differences”)
    Creates message:
    “ageDifference must be greater than zero when calculating age differences”
    Throws exception:
    PostconditionException

    and also:
    Ensure(Of Decimal).That(ageDifference).IsGreaterThan(0).AndShow(“ageDifference must be greater than zero”).AndThrow(GetType(AgeDifferenceException).Whenever(“calculating age differences”)
    Creates message:
    “ageDifference must be greater than zero when calculating age differences”
    Throws exception:
    AgeDifferenceException
    With inner exception:
    PostconditionException

    I still like When or Whenever at the tail…

  • jlockwood

    @Ocampo:
    “Caution when throwing exceptions in a fluent interface.”

    I agree, that’s why my preferred method is to allow the checks to throw their own exceptions, catch them in the business object, and propagate them as inner exceptions.
    I often have methods in the business objects for pre/post-operation checks, etc. that use the try/catch to package the exception for error propagation.

  • jlockwood

    Ocampo – “SideNote: I would encourage refactoring to Generics but I ran out of time. After all this is a comment!”

    @Ocampo: It was a little bit of a pain in the rear and this is one are where I’m not sure how I feel about the implementation. I have default delegates defined for operations such as IsNotNull, IsGreaterThan, etc. IsNotNull works for classes, but not primitives/structs. IsGreaterThan works for primitives, but not necessarily for classes (could have a IComparable constraint on the type). By default right now I have most checks throwing exceptions, but I could probably GetHashCode and use that for comparisons by default.

    For type-specific checks, I interrogate the generic’s type on construction and then (currently at least) go through a switch to wire up appropriate delegates (for instance, Decimal type has it’s own IsGreaterThan and again I may go to using the hash).

  • jlockwood

    Side note:
    McCafferty also referenced Eiffel’s:
    Building bug-free O-O software: An introduction to Design by Contract(TM)
    http://archive.eiffel.com/doc/manuals/technology/contract/

    This also shows the use of the Require/Ensure concepts. It also shows (which is arguably easier/cleaner in eiffel) how multiple conditions are evaluated together, making for some interesting possibilities for us syntactically. Such as:
    Ensure(Of Decimal). _
    That(ageDifference).IsGreaterThan(0). _
    And(Of Boolean). _
    That(eldest.IsLiving).IsTrue(). _
    Whenever(“calculating age differences”). _
    - or -
    Require(Of Person). _
    That(joshua).HasMoreThanOneFriend(). _
    Or(). _
    That(ocampo).ThinksIsCool(joshua). _
    Whenever(“Joshua threatens to speak at a user group meeting”)

    …this would be so much easier in ruby…

  • http://blog.jasonmeridth.com Jason Meridth

    Alright guys, each of these comments deserves a post unto itself.

    Great thread Sean.

  • http://www.lostechies.com/blogs/joe_ocampo/ Joe Ocampo

    @Josh
    >Require: precondition check

    >Ensure: postcondition check

    Rather than relying on the the implicit symantecs behavior of “Require” and “Ensure” can we just explicitly use this instead.

    PreConditionShouldRequire(Decimal).That(ageDifference).IsGreaterThan(0).Whenever(“calculating age differences”)

    PostConditionShouldEnsure(Decimal).That(ageDifference).IsGreaterThan(0).Whenever(“calculating age differences”)

    Now we have the best of both worlds. That is if you speak “English”! :-)

  • jlockwood

    @Joe:
    “Now we have the best of both worlds. That is if you speak “English”!”

    Si, hablo ingles bien, pero pienso que con “Require” y “Ensure” lee mas agradable (es mas bonito). But I do see you point and may well adopt it (or something similar) if the people who are adopting the app once are confused.

  • http://www.lostechies.com/blogs/sean_chambers Sean Chambers

    Wow, great points guys.

    Josh, Can you supply the classes you have been using so we can take a look? I would like to expand my classes a little more when I have a chance.

    I think I am going to start a FluentDBC google group so we can move the discussion there perhaps? The comments on this thread are getting a little long.

    What does everyone else think?

  • http://www.lostechies.com/blogs/joe_ocampo/ Joe Ocampo

    Sounds like a Plan. Personally I was see how far we could take CS 2007. :-)

  • jlockwood

    @Sean
    Tell us when and where…we could also use the AlamoCoders forum (the web nazis are less likely to block that).

    I can get you my classes later today if you wish, I’m in the middle of something right now.

  • http://www.lostechies.com/blogs/sean_chambers Sean Chambers

    Lets use the alamo coders forum. That would be cool.

    I will see about setting up a seperate Google Code repository for just this project. This way it isn’t tied specifically to my code repository.

    I have a couple of things to do this afternoon so I may not get to this stuff till tomorrow anyways.

    ttyl!

  • jlockwood

    I forgot my logon for AlamoCoders, I put the file here for the time being:
    http://www.lostechies.com/files/folders/examplesource/entry1052.aspx

  • http://ajdotnet.wordpress.com aj.net

    Two comments:
    #1: fluent interfaces
    I actually don’t quite understand what all that talk about fluent interfaces is about! Granted, the term has been formally introduced by Fowler in Dec 07, but it is not that new. It was a common pattern with C++ to return a reference to itself from a method rather than declaring it void. E.g. one could write:
    CString s= “fluent interface”;
    s.MakeUpper().MakerReverse().Delete(0, 99);

    What I don’t like about fluent interfaces is that you don’t know from the looks of the code, what you are dealing with. It might include “fluent interface calls” as well as simple method calls on returned objects. Is it a reference to the object itself, a copy, another object? Or null? Which leads to the questing how one will track down a NullReferenceException (or other) in such a call chain.

    Fowler (http://martinfowler.com/bliki/FluentInterface.html) had the folowing example of a fluent interface:

    private void makeFluent(Customer customer) {
    customer.newOrder()
    .with(6, “TAL”)
    .with(5, “HPK”).skippable()
    .with(3, “LGV”)
    .priorityRush();
    }

    This was a rewrite of some ugly sample code. That ugly code could have been improved by simply cleaning it up a bit. Some small helper methods could further help, e.g. the following fragment is just as clean as the above code:

    private void makeBetter(Customer customer) {
    Order o1 = CreateNewRushedOrder(customer);
    AddLine(o1, 6, “TAL”);

    AddLine(o1, 5, “HPK”, Options.Skippable);
    AddLine(o1, 3, “LGV”);

    }

    No fluent interfaces needed. So why introduce a new pattern, thus add complexity, if it does not provide some additional value?

    #2: Check class
    Why rewrite
    Check.Require(!string.IsNullOrEmpty(username), “username is required”);
    to
    Check.Parameter(username).WithMessage(“username is required”).IsNotNullOrEmpty();
    ?

    What happened to
    Guard.AssertNotEmpty(username, “username”, “username is required”);
    ?
    Readable, concise, and consistent exceptions

    Just my 0,02€.
    AJ.NET

  • http://www.lostechies.com/blogs/sean_chambers Sean Chambers

    AJ,

    Fair enough.

    I do agree that a fluent interface is difficult to read from the actual classes that make it possible. You really need to use the fluent interface to see how it works. Once you do that, then it’s easy to dive in and understand how the code is actually setup.

    Whether or not this is an ample situation for fluent interfaces or not is actually a good question. With the original article by Bill, you had to do tricky assertions as my example above states. This is what motivated me to use a fluent interface. I suppose it was more of an example than anyhting else.

    I wanted for the assertion to read more like a sentance than an assertion to make the code more soluable which is why I made it that way. I felt it was more concise than not using it.

    Good points!

  • http://www.lostechies.com/blogs/joe_ocampo/ Joe Ocampo

    It is important to note that method chaining and fluent interfaces differ significantly.

    Fluent interfaces compliment an internal DSL’s behavior an the interaction between the language constructs that form the DSL.

    Method chaining is simply returning the same instance out of the given method that you are invoking against that object.

    Fluent interfaces enforce DSL’s through class delegation upon the architecture. Meaning I can’t invoke the addProduct() Method unless I have created an Order with a customer.

    Make sense?

  • http://www.lostechies.com/members/colinjack/default.aspx colinjack
  • Nestor

    I have been seen PostSharp from some time ago, and wondering if I could have attributes that get validation code injected in the class, avoiding errors and space on the source code.
    Finally I used Billy’s library as a base runtime and got a PostSharp post compilation process that get validation automagically applied to all parameters, including options as defining a whole namespace defaulted to not null or thing like that out of the box, many thanks to Gael for his PostSharp library, its rock!.

    Regards