IFluentInterface

The core interface to implement fluent APIs that hide the default System.Object members.


Keywords
API, fluent
License
Apache-2.0
Install
Install-Package IFluentInterface -Version 2.1.0

Documentation

Icon IFluentInterface

NuGet downloads Version

In modern fluent APIs, method chaining is a key techique for intuitive discovery of valid options when configuring some underlying object.

In these scenarios, System.Object methods (Equals, GetHashCode, GetType and ToString) only contribute clutter to Visual Studio intellisense. Everyone knows those members are always there, yet they are seldom used explicitly. This is quite annoying for fluent APIs that define the flow of invocations in terms of interfaces and usually have few members at each "step" of the method chaining statement.

For example, in the following Moq setup, at the particular step in the statement, there is only one "real" invocation that makes sense (Verifiable). However, it is obscured by the System.Object members:

Full Intellisense

A much cleaner intellisense is possible though, by simply inherinting your fluent API interfaces from the IFluentInterface interface provided by this project:

Clean Intellisense

How to Install

IFluentInterface is a single interface definition file with no external dependencies whatsoever and is distributed as a NuGet package. It can be installed issuing the following command in the Package Manager Console:

PM> Install-Package IFluentInterface

After installation, the IFluentInterface file will be added to your project root, and its target namespace will match the current project's. There are no associated binaries at all.

How it Works

The trick comes from the EditorBrowsableAttribute, which controls visibility of members in VS intellisense. To hide a member from intellisense, you apply the following attribute to it:

[EditorBrowsable(EditorBrowsableState.Never)]

Now, you don’t want to have to override all four object members in every type just to apply the attribute. A quite elegant solution exists, which involves taking advantage of implicit interface implementation. In particular, you can define an interface that re-defines all object members and applies the attribute:

[EditorBrowsable(EditorBrowsableState.Never)]
public interface IFluentInterface
{
    [EditorBrowsable(EditorBrowsableState.Never)]
    Type GetType();
 
    [EditorBrowsable(EditorBrowsableState.Never)]
    int GetHashCode();
 
    [EditorBrowsable(EditorBrowsableState.Never)]
    string ToString();
 
    [EditorBrowsable(EditorBrowsableState.Never)]
    bool Equals(object obj);
}

Now you simply "implement" this interface in all your classes or interfaces where you want to hide these members, like:

public interface IVerifies : IFluentInterface

Who's Using This?

Pretty much every project that has a fluent API. Over time, I’ve started liking the IFluentInterface name better than my original IHideObjectMembers, but you can also find this interface defined as IFluentSyntax too.

As of 11/2017, I've found 230+ repositories using IFluentInterface, 280+ using IHideObjectMembers and 30+ using IFluentSyntax, on GitHub only!

Credits

If you do leverage this technique, please maintain the original file credits as shown in the source file. Our preference is for you to just install the IFluentInterface nuget to get the interface and keep it up to date.

Icon courtesy of The Noun Project