Model Binding isn’t just for the web

It’s a given that your web framework of choice has some form of model binding built-in. Maybe you’re lucky enough to have Content Negotation on top of that but regardless, there is some mechanism to transform the incoming HTTP message to a well-formed type for you to consume.

When I first started using these binding mechanisms, I found myself asking a few questions:

  • Is there a way to extend the standard converters?
  • Is there any easy way to distribute common extensions?

Frameworks at the time were working to answer those questions and that was fine. But then I started to wonder some more:

  • What if we could do conversions more conventionally?
  • What about common practices with value types?
  • How about we bind common properties via some known service for testing (e.g., CurrentDate, CurrentUser)?

You’re probably thinking that this the part where I do my obligatory plug for Fubu. Well, you’re absolutely right.

Model Binding in Fubu

Most people are not aware of the separation between FubuMVC and FubuCore. That is, they hear about something in the world of Fubu and think that they would only be able to leverage it if they were using the whole stack. Well, that’s just not true and plenty users of HtmlTags would tell you all about it. I say this because Model Binding just happens to be another gem that is found in FubuCore.

Our binding uses the notion of a source of values (aka IValueSource). My common explanation for this is: “Imagine if you iterated over your design a few times going from a dictionary, to a value type, abstracted that, and then made everything compatible with testing and diagnostics”. That would be IValueSource.

So, why do you care? And why is this applicable outside of the web? Let’s look at some example IValueSource implementations:

Web

This one’s a no-brainer. There are value sources in FubuMVC that make route and request data available to the binder.

Settings

This one is a favorite that I take for granted. Settings data can come from anywhere (app/web config, database, etc.). You can adapt that information into an IValueSource (we have common structures for this — including a generic dictionary version) and feed it into the binding.  This makes complex property settings easily possible (e.g., MySettings.NestedObject.Name = “Test”)

Comma-Separated-Values

That’s right. Everyone’s favorite integration technique is something that’s supported OOTB in FubuCore. You can map your DTO classes using a FluentHibernate-esque column mapping and pull out your objects through the model binding subsystem to give you ultimate flexibility in your parsing.

Other examples I’ve seen

I’ve seen teams write custom rule engines that serialize data into dictionary-like formats for NoSQL storage and then pass the values back through model binding to execute the rules. I’ve also seen similar techniques used for widget-crazy-dashboards.

If you take anything away from this, let it be this

Binding classes from data is a highly useful function. A binding subsystem that is configurable and DI-enabled is invaluable. If you haven’t checked out the binding in FubuCore, then I hope this will tug at your curiosity enough to make you take a look.

Additional Resources

For further reading on how FubuCore’s model binding works and what you can do with it, I highly recommend Chad’s post:

Related Articles:

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

About Josh Arnold

Josh is team lead at Extend Health and a principal developer on the Fubu-family of frameworks. He is a proud husband, terrified but excited father, passionate software guy and coach, closet musician, aspiring man of God, and a perpetual learner.
This entry was posted in General. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • darrencauthon

    IValueSource has a WriteReport method.

    throw new MethodNotImplementedException(); ?

    • jmarnold

      Diagnostics is a first class citizen. This is why that method is there.

      There are a handful of generic/reusable implementations of IValueSource that take care of all the details for you and let you work with more primitive types (e.g., IDictionary).

      • darrencauthon

        I thought Fubu was all about SOLID?  SRP?

        • jmarnold

          That may be true, but it’s not dogmatic for sake of being unreasonable. SOLID is a vehicle for helping us implement our vision. One important part of that vision happens to be traceability.

          When push comes to shove, I think it’s OK to let that vision drive a design decision even if it’s a little on the awkward side (i.e., forcing you to implement a no-op).

          It’s not something we take lightly. We obsess over those decisions for some time before biting the bullet.

          • darrencauthon

            I don’t mean to be a troll about this, but seeing this method on this class blew me away.  You say that testing and diagnostics are important, but what’s the method?  ”WriteReport”.  Write a report about what?  What if I want a report that doesn’t fit IValueReport? (which, btw, has a dependency tossed right back to IValueSource, on some method called “StartSource”)  

            This seems like a textbook “before” refactoring example, where the teacher gets the class to identify which part doesn’t fit.  The “after” is always to separate the two responsibilities into their own separate class.  But to knowingly mix these two, and at such a low-level thing like a “value source,” doesn’t seem that useful at all.  In all of the places that devs use “value sources” for settings, form post data, CSVs, or whatever, no one ever says “Ok, the work’s done, now it’s time to add a report.”

            I’ve been doing Ruby full-time for a year or so.  Do you know what we call “the notion of a source of values?”  An object.

          • jmarnold

            I think you’re focusing on the wrong thing here. At no point in the process does the API require anyone to implement IValueSource. I’m thinking that I miscommunicated that.

            IValueSource is the lowest level interface we have. We have APIs that sit on top of this ad make everything much more seemless.
            Think about it more like this: you provide data and we do the magic. On top of that, we provide detailed diagnostics to answer the “what/who/how/why” of the entire process.I’m not going to split hairs with you on Ruby vs. .NET. Different strokes, man. If you’re in a static language and WANT to use it, then this lets you do exactly that.

          • darrencauthon

            “You provide the data and we do the magic.”  

            That’s the thing — the “us” in FUBU seems to be a tight group.  The call to put a “WriteReport” in such a low-level interface, and from scratch (it was included in the first commit) seems so obtuse, and I’d be really surprised that there’s no backlash against that.  I’ve shown this interface to a few of my programming friends with a simple question “What is wrong here?” and everybody pointed at that method.   The same benefits could be had by putting it in another interface and tagging both on any implementing class.  

            I don’t mean to make it a Ruby/C# thing, I’m just trying to point out that the thing being abstracted is, essentially, an object.  

            Don’t worry, I won’t keep pestering you on this. :)  Have a good weekend!

          • jmarnold

            Hey, you know I always appreciate constructive criticism, Darren. 

            I think the biggest mistake with this post was approaching it from a “Hey, check out this interface” vs. “Hey, look at this sample code that uses it”.

            I’m not saying that the method isn’t awkward. It’s a visitor pattern that just didn’t have a great place to go without introducing unnecessary complexity in achieving the goals we had.