What Do You Think Of This Hack?

14 commentsWritten on November 16th, 2010 by
Categories: C#, Code Quality

I have a class which exposes a fluent interface to build something. Instances of this class contain some state based on the methods of the fluent interface you called and the arguments you passed to those methods. Now, that state is currently private but it's not private in the "oh my god we need to encapsulate this so nobody can read it!11!!!1" sense. In fact, i actually want to access that state from another class. The only 'problem' is that i don't want to add methods or properties to the class to expose this state, because it sort-of pollutes the fluent interface. I know, that's not really a huge issue but still, it'd be nice to keep the fluent interface clean and focused.

One way to expose this state without polluting the fluent interface is to create a separate interface which defines the methods/properties and then have the class implement that interface explicitly. That way you could only access those methods/properties when you cast the instance to the interface type. While there's nothing really wrong with doing that, i kinda have a bad feeling about that because it introduces an interface which is only there to support this little exercise in Intellectual Masturbation.

Instead, i tried this:

    public class MyClassWhichUsesAFluentInterface
    {
        private List<string> someState = new List<string>();

        public MyClassWhichUsesAFluentInterface SomethingFluent(string blah)
        {
            someState.Add(blah);
            return this;
        }

        // ...

        public static List<string> GetState(MyClassWhichUsesAFluentInterface constructedThingie)
        {
            return constructedThingie.someState;
        }
    }

Is it fancy? nope. Is it cool? nope. Does it work? yup. Is it simple? yup.

Good enough for me.

  • Kivela

    Could you at least give us some context about the specific problem at hand ?

    I am not a big fan of intellectual masturbation either, because it kinds of spoils the whole idea of the latter but it should be handy to have some insights into why you want to use the state from another class and not expose it, at the moment (without context) it sounds a little bit as if the responsibility of state manipulation could be specified wrong.

    Knowing you a little I can’t imagine such a violation, so do enlighten us a bit.

  • http://odalet.wordpress.com Olivier

    Nothing wrong with this to me. By the way when one wants to provide a fluent interface, we often use tricks (extension methods, attributes and so on) to obtain a clean Intellisense experience, so the explicit interface implementation just seems to me another trick in the fluent interface builder toolbelt…

  • http://davybrion.com Davy Brion

    @Kivela

    that state is needed to perform some security related checks, which (arguably) isn’t really the responsibility of the class exposing the fluent interface.

    the only reason i don’t want to expose it through regular public properties/methods is simply because it would pollute the fluent interface. it’s not data that needs to be hidden or anything.

  • http://benpittoors.wordpress.com den Ben

    Is it cool? you could argue about that :) What if I think it is cool access the internals of an instance by using a static method?

  • http://davybrion.com Davy Brion

    @Den Ben

    i’d say it’s because you’re vintage :p

  • http://kenegozi.com/blog Ken Egozi

    Works and Simple comes way before anything else.

    BTW, the explicit interface way is something I also exploit in weird way. I sometimes add a ISomethingWithTestAccess instead of using internal and InternalsVisibleTo. On other times I do a public static method like the one described here.

    Works
    Simple

  • http://elegantcode.com Jan Van Ryswyck

    If you want to get a hand of the internal state, why encapsulate it then? How about providing a number of extension methods on List for your fluent interface and use the list directly? Just a thought as we don’t have the full context here.

  • http://www.diogomafra.com.br/ Diogo Edegar Mafra

    If you are going to use it only in a very specific case, maybe you could use the “EditorBrowsableAttribute”.

    http://msdn.microsoft.com/en-us/library/system.componentmodel.editorbrowsableattribute.aspx

    Just one note: “In Visual C#, EditorBrowsableAttribute does not suppress members from a class in the same assembly.”

  • Nick

    Why not just have one property that is composed of all the properties you don’t want as part of the fluent interface?

  • bennyb

    instead of
    var myClass = SomeClass(){Name = name, Age = age};

    you can do:
    var myClass = new SomeClass().setName(name).setAge(age);

  • http://blog.dbrtacer.org footcha

    What about this?

    public class MyClassWhichUsesAFluentInterface
    {
    internal List someState = new List();
    }

    public static FluentInterfaceUtil
    {
    public static List GetState(MyClassWhichUsesAFluentInterface constructedThingie)
    {
    return constructedThingie.someState;
    }
    }

    Your fluent interface class is not polluted and you have access to state of it.

  • http://thinkbeforecoding.com thinkbeforecoding

    You could even replace your static method with an explicit or implicit cast…

  • Nima

    How about something like this:
    (a php like approach)

    public T static GetState(FluentObject obj, string name)
    {
    //return the state;
    }

    or an indexer in your fluent interface

    public object this[string name]
    {
    get
    {
    //return the state;
    }
    }

    this way you can get what you like whenever you like.

  • Dennis