Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 538971
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 13, 20262026-05-13T10:05:15+00:00 2026-05-13T10:05:15+00:00

Sorry for this long question, it is flagged wiki since I’m asking for something

  • 0

Sorry for this long question, it is flagged wiki since I’m asking for something that might not have a very concrete answer. If it is closed, so be it.

My main question is this:

How would you write a fluent interface that isn’t fully defined in the base classes, so that programs that uses the fluent interfaces can tack on new words inside the existing structure, and still maintain a guiding interface so that after a dot, the intellisense only lists the keywords that actually apply at this point.


I’m on my 3rd iteration of rewriting my IoC container. The 2nd iteration was to improve performance, this third iteration will be to solve some extensibility problems, and separation-problems.

Basically, the problem with extensibility is that there is none. I recently wanted to use a service that had a lifetime, and after the lifetime had expired, resolve a fresh copy. For instance, read a config file every minute, but not more often. This was not supported by my current IoC solution, but the only way to add it was to go into the base class library and add support for it there. This means to me that I’ve failed to build an extensible class library. In all fairness, I didn’t intend to build extensibility into it, but then I didn’t fully appreciate how much pain it would be to go in and add something like this later.

I’m looking at my fluent interface for configuration, and since I want to build full extensibility into the interface as well (or get rid of it, which I’m loath to do) I need to do things differently.

As such, I need your opinion. I have very little experience actually using fluent interfaces, but I’ve seen quite a bit of code that uses them, and as such there is one obvious benefit right out of the box:

  • Code that uses fluent interfaces are usually very easy to read

In other words, this:

ServiceContainer.Register<ISomeService>()
    .From.ConcreteType<SomeService>()
    .For.Policy("DEBUG")
    .With.Scope.Container()
    .And.With.Parameters
        .Add<String>("connectionString", "Provider=....")
        .Add<Boolean>("optimizeSql", true);

is easier to read than this:

ServiceContainer.Register(typeof(ISomeService), typeof(SomeService),
    "DEBUG", ServiceScope.Container, new Object[] { "Provider=...", true });

So readability is one issue.

However, programmer guidance is another, something which isn’t easily understood by reading existing code, on the web or in an editor.

Basically, when I type this:

ServiceContainer.Register<ISomeService>()
    .From.|
          ^-cursor here

and then intellisense will show the available resolution types. After I’ve picked that one, and write:

ServiceContainer.Register<ISomeService>()
    .From.ConcreteType<SomeService>()
    .For.|

then I only get things available after the “For” keyword, like “Policy” and such.

However, is this a big issue? Have fluent interfaces you’ve used been like this? The obvious cop-out to define the interface is to make a class, or an interface, with all the keywords, and everything, so that intellisense after each comma contains everything, but this could also lead to this being legal (as in, it compiles) code:

ServiceContainer.Register<ISomeService>()
    .From.ConcreteType<SomeService>()
    .From.Delegate(() => new SomeService())
    .From.With.For.Policy("Test");

so I’d like to structure the fluent interfaces such that after you’ve specified how to resolve a service, you cannot do that again.

  • In other words, fluent interfaces are very easy to use, since they guide you towards what you can do.

But is this typical? Since I want to be able to add a bunch of these keywords, like the type of resolver (ConcreteType, Delegate, etc.), the type of scope (Factory, Container, Singleton, Cache, etc.) as extension methods, so that programs can define their own ways to do this without having to go in and change the base classes, it means I’ll need to provide interfaces for all the intermediate stops, and let the actual important keywords be. The implementation for those keywords then have to pick one intermediate-stop-interface to return, as appropriate.

So it looks like I need to define an interface for:

  • xyz.From.
  • xyz.From.<Resolver here>.
  • <Resolver here>.With.
  • <Resolver here>.For.

etc. but that looks fragmented to me.

Can anyone with experience with fluent interfaces go back and read my quoted answer near the top and try to give me a short answer?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-13T10:05:15+00:00Added an answer on May 13, 2026 at 10:05 am

    Two things: Extension methods and nested closures. They should cover all your extensibility and intellisense clarity needs.


    If you’re interested, here’s a couple of tips from my experience building Fluent NHibernate.

    Method chaining should be kept to a minimum. It leads to dead-ending and an indefinite end to the call-chain, among other things. Prefer nested closures.

    For example, dead-ending:

    Database
      .ConnectionString
        .User("name")
        .Password("xxx")
      .Timeout(100) // not possible
    

    You can’t get back to the Database chain once you’ve entered the ConnectionString chain, because there’s no way back up with all the connection-string related methods returning an instance of ConnectionString.

    You could rewrite it with a definite-end method, but they’re ugly.

    Database
      .ConnectionString
        .User("name")
        .Pass("xxx")
        .Done()
      .Timeout(100)
    

    Where in this case, Done would return the Database instance, returning you to the primary chain. Again, ugly.

    As suggested, prefer nested closures.

    Database
      .ConnectionString(cs =>
        cs.User("name");
          .Pass("xxx"))
      .Timeout(100);
    

    That pretty much covers your intellisense issues, as closures are fairly self-contained. Your top-level object will only contain the methods that take closures, and those closures only contain the methods specific to that operation. Extensibility is also easy here, because you can add extension methods just to the types that are exposed inside the closures.

    You should also be aware to not try to make your fluent interface read like english. UseThis.And.Do.That.With.This.BecauseOf.That chains only serve to complicate your interface when the verbs would suffice.

    Database
      .Using.Driver<DatabaseDriver>()
      .And.Using.Dialect<SQL>()
      .If.IsTrue(someBool)
    

    Versus:

    Database
      .Driver<DatabaseDriver>()
      .Dialect<SQL>()
      .If(someBool)
    

    Discoverability in intellisense is reduced, because people tend to look for the verb and fail to find it. An example of this from FNH would be the WithTableName method, where people tend to look for the word table and not find it because the method starts with with.

    Your interface also becomes more difficult to use for non-native english language speakers. While most non-native speakers will know the technical terms for what they’re looking for, the extra words may not be clear to them.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Firstly, sorry about the long question... but this is doing my head in. Any
Sorry for a long question but here goes. I am trying to modify the
Sorry in advance for the long question, it's long because I've been digging at
I have a quite long and (for me) complex question. I have voting data
This is a hard one to explain but here goes. I have 2 arrays,
I have a query that attempts to find things within a certain geolocation, but
I have huge data matrices stored in a MATLAB M-file and I will explain
Here is my first question about maximum L sum and here is different and
Reading about and using the Amazon Web Services, I'm not really able to grasp
How would you go about embedding youtube vidoes automatically from the URI. Say for

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.