FubuMVC Lessons Learned — Magic Conventions, Russian Dolls, and Ceremonial Code

tl;dr: FubuMVC stressed concise code and conventions over writing explicit code and that turns out to be polarizing

The typical way to be successful in OSS is to promote the hell out of your work before you give up on it, but I’m under a lot less pressure after giving up on FubuMVC and I feel like blogging again.  Over the next couple months I’m going to write about the technical approach we took on FubuMVC to share the things I think went well, the stuff I regret, how I wish we’d done it instead, discarded plans for 2.0, and how I’d do things differently if I’m ever stupid enough to try this again on a different platform.

 

Some Sample Code

So let’s say that you start a new FubuMVC project and solution from scratch (a topic for another blog post) by running:

fubu new Demo --options spark

You’ll get this (largely placeholder) code for the MVC controller part of the main home page of your new application:

namespace Demo
{
        // You'd generally do *something* in this method, otherwise
        // it's just some junk code to make it easier for FubuMVC
        // to hang a Spark or Razor view off the "/" route
        // For 2.0, we wanted to introduce an optional convention
        // to use an "action less view" for the home page
	public class HomeEndpoint
	{
		public HomeModel Index(HomeModel model)
		{
			return model;
		}
	}
}

To make things a little more clear, fubu new also generates a matching Spark view called Home.spark to render a HomeModel resource:

<viewdata model="Demo.HomeModel" />

<content:header></content:header>

<content:main>
Your content would go here
</content:main>

<content:footer></content:footer>

The code above demonstrates a built in naming convention in FubuMVC 1.0+ such that the home “/” route will point to the action “HomeEndpoint.Index()” if that class and method exists in the main application assembly.

Some additional endpoints (FubuMVC’s analogue to Controller’s in MVC frameworks) might look like the following:

    public class NameInput
    {
        public string Name { get; set; }
    }

    public class Query
    {
        public int From { get; set; }
        public int To { get; set; }
    }

    public class Results { }

    public class MoreEndpoints
    {
        // GET: name/{Name}
        public string get_name_Name(NameInput input)
        {
            return "My name is " + input.Name;
        }

        // POST: query/{From}/to/{To}
        public Results post_query_From_to_To(Query query)
        {
            return new Results();
        }
    }

 

What you’re not seeing in the code above:

  • No reference whatsoever to the FubuMVC.Core namespace.
  • No model binding invocation
  • No code to render views, write output, set HTTP headers
  • No code for authentication, authorization, or validation
  • No “BaseController” or “ApiController” or “CoupleMyCodeVeryTightlyToTheFrameworkGuts” base class
  • No attributes
  • No marker interfaces
  • No custom fluent interfaces that render your application code almost completely useless outside of the context of the web framework you’re using

What you are seeing in the code above:

  • Concrete classes that are suffixed with “Endpoint” or “Endpoints.”  This is an out of the box naming convention in FubuMVC that marks these classes as being Action’s.
  • Public methods that take in 0 or 1 inputs and return a single “resource” model (they can be void methods too).
  • Route patterns are derived from the method names and properties of the input model — more on this in a later post because this one’s already too long.

 

One Model In, One Model Out and Automatic Content Negotiation

As a direct reaction to ASP.Net MVC, the overriding philosophy from the very beginning was to make the code we wrote be as clean and terse as possible with as little coupling from the application to the framework code as possible.  We also believed very strongly in object composition in contrast to most of the frameworks of the time that required inheritance models.

To meet this goal, our core design idea from the beginning was the one model in, one model out principle.  By and large, most endpoints should be built by declaring an input model of everything the action needs to perform its work and returning the resource or response model object.  The framework itself would do most of the repetitive work of reading the HTTP request and writing things out to the HTTP response for you so that you can concentrate on only the responsibilities that are really different between actions.

At runtime, FubuMVC is executing content negotiation (conneg) to read the declared inputs (see the NameModel class above and how it’s used) from the HTTP request with a typical combination of model binding or deserialization, calling the action methods with the right input, and then rendering the resource (like HomeModel in the HomeEndpoint.Index() method) again with content negotiation.  As of FubuMVC 1.0, rendering views are integrated into the normal content negotiation infrastructure (and that ladies and gentlemen, was a huge win for our internals).    Exactly what content negotiation can read and write is largely determined by OOTB conventions.  For example:

  • If a method returns a string, then we write that string with the content-type of “text/plain”
  • If an action method returns a resource model, we try to “attach” a view that renders that very resource model type
  • In the absence of any other reader/writer policies, FubuMVC attaches Json and Xml support automatically with model binding for content-type=”application/x-www-form-urlencoded” requests

The automatic content negotiation conventions largely means that FubuMVC action methods just don’t have to be concerned about the details of how the response is going to be written out.

View resolution is done conventionally as well.  The easiest, simplest thing to do is to simply make your strongly typed Spark or Razor view render the resource model type (the return type) of an action method and FubuMVC will automatically apply that view to the matching action.  I definitely believe that this was an improvement over the ASP.Net MVC ViewResult mechanism and some other frameworks *cough* NancyFx *cough* adapted this idea after us.

The huge advantage of the one model in, one model out was that your action methods became very clean and completely decoupled from the framework.  The pattern was specifically designed to make unit testing action methods easy, and by and large I feel like we met that goal.  It’s also been possible to reuse FubuMVC endpoint code in contexts outside of a web request because there is no coupling to FubuMVC itself in most of the action methods, and I think that’s been a big win from time to time.  Try to do that with Web API, ASP.Net MVC, or a Sinatra-flavored framework like NancyFx!

The downside was the times when you really did need to exert more fine grained control over HTTP requests and responses.  While you could always happily take in constructor dependencies to read and write to the raw HTTP request/response, this wasn’t all that obvious.

 

The Russian Doll Behavioral Model

I’ve regretted the name “FubuMVC” almost from the beginning because we weren’t really a Model 2 MVC framework.  Our “Action” methods just perform some work within an HTTP request, but don’t really act as logical “Controller’s.”  It was also perfectly possible to build endpoints without Action methods and other endpoints that used multiple Action methods.

The core of FubuMVC’s runtime was the Russian Doll “Behavior” model I described way back in 2011 — in which action methods are called inside of a pre-built Behavior in the middle of a chain.  For example, our HomeEndpoint.Index() action above has a chain of nested behaviors in real life something like:

  1. AuthenticationBehavior
  2. InputBehavior — does content negotiation on the request to build the HomeModel input
  3. ActionCall –> HomeEndpoint.Index() — executes the action method with the input read by conneg and stores the output resource for later
  4. OutputBehavior — does conneg on the resource and “accepts” header to write the HTTP response accordingly

FubuMVC heavily uses additional Behavior’s for cross cutting concerns like authorization, validation, caching, and instrumentation that can be added into a chain of behavior to compose an HTTP pipeline.  Every web framework worth its salt has some kind of model like this, but FubuMVC took it farther by standardizing on a single abstraction for behaviors (everything is just a behavior) and exposing a model that allowed you to customize the chain of behaviors by either convention or explicitly on a single endpoint/route.

In my opinion, the Behavior model gave FubuMVC far more modularity, extensibility, and composability than our peers.  I would go so far as to say that this concept has been validated by the sheer number of other frameworks like Microsoft’s WebAPI that have adopted some form of this pattern.

 

Clean, terse “magical” code versus explicit code

The downside to the behavior model, and especially FubuMVC’s conventional construction of the nested Behaviors is the “magical” aspect.  Because the framework itself is doing so much more work for you, there isn’t a blob of explicit code in one place that tells a developer everything that’s happening in an HTTP request.  In retrospect, even though I personally wanna write the tightest, most concise code possible and avoid repetitive code, other developers are much happier writing and reading code that’s much more explicit — even when that requires them to write much more repetitive code.  It turns out that repetitive code ceremony is not a bad thing to a large number of developers. 

Other developers hated the way that FubuMVC doesn’t really do much to lead you to what to do next or make the framework capabilities discoverable because so much of the code was meant to be driven by FubuMVC conventions based on what your code looked like rather than you writing explicit code against FubuMVC API’s with Intellisense there to guide you along the way.  And yes, I’m fully cognizant that I just make an argument in favor of a Sinatra style fluent interface like NancyFx’s.  I know full well that many developers considered NancyFx much easier to learn than FubuMVC because of Nancy’s better discoverability.

We did offset the “magical” problem with diagnostics that I’ll discuss at a later time, but I think that the “magical” aspect of FubuMVC scared a lot of potential users away in retrospect.  If I had it to do over again, I think I would have pushed to standardize and describe our built in conventions much earlier than we did — but that’s another blog post altogether.

 

What I wanted to do in FubuMVC 2.0 

I had no intention of adopting a programming model more like Sinatra or Web API where you write more explicit code.  My feeling is that there is room in the world for more than one basic approach, so for 2.0, I wanted to double down on the “one model in, one model out” approach by extending more conventions for finer grained control over the HTTP request & response without losing the benefits.  Things like:

  • More built in model binding conventions to attach Cookie values, system clock values, IPrincipal’s, and whatever else I could think of into the OOTB model binding.
  • Built in conventions for writing header, response codes, and cookie values from resource model values to maintain the one model in, one model out motif while still allowing for more powerful HTTP API capabilities
  • We did change the content negotiation defaults to make views “additive” to Json/Xml endpoints, so that any endpoint that renders a view for accept=”text/html” can also return Json or Xml by default
  • We made it a little easier to replace the built in Json/Xml serialization
  • We did streamline the content negotiation internals to make customization smoother
  • Add new built in conventions to attach custom content negotiation readers and writers to the appropriate input and resource types

 

I’m throwing in the towel in FubuMVC

tl;dr:  I’m giving up on fubu and effectively retiring from OSS on .Net

 

Some things came to a head last week and I announced that I’m planning to cease work on FubuMVC after finishing some performance and startup time optimization work as a 2.0 release — which right now means that FubuMVC and its very large ecosystem of surrounding projects is effectively kaput.  Even just a couple weeks ago I was still excited for our 2.0 release and making big plans, but the writing has been on the wall for quite some time that FubuMVC no longer has enough community support to be viable and that the effort I think it would take to possibly change that situation probably isn’t worth it.

For me personally, FubuMVC has turned out to be a fantastic experience in my own learning and problem solving growth.  My current position is directly attributable to FubuMVC and I’ve generally enjoyed much of the technical work I’ve gotten to do over the past 2-3 years.  I’ve forged new relationships with the folks who I met through my work on FubuMVC.

On the downside, it’s also been a massive opportunity cost because of all the things I haven’t learned or done in the meantime because FubuMVC takes up so much of my time and that’s the main reason that it has to stop now.

Some History

 

Rewind to the summer of 2008.  I had just started a new job where we were going to do a big rewrite of my new company’s website application.  My little team had a choice in front of us, we could either choose Ruby on Rails (the hot thing of the day) or continue with .Net and use the brand new ASP.Net MVC framework coming down the pike.  If I had it all to do again, I would choose RoR in a heartbeat and just have gotten on with getting the project done.  At the time though, the team previous to us had completely flopped with RoR (not for technical reasons) and the company was understandably leery of using Rails again.  At the same time, this was at the tail end of the ALT.Net movement and I felt very optimistic about .Net at the time.  Plus, I had a large personal investment in StructureMap and Fluent NHibernate (yes Virginia, there was a time when we thought ORM’s were a good idea).

We opted for .Net and started working on early versions of ASP.Net MVC.  For various reasons, I disliked MVC almost immediately and started to envision a different way of expressing HTTP endpoints that wouldn’t require so much coupling to the framework, less cruft code, and better testability at the unit level.  For a little while we tried to work within ASP.Net MVC by customizing it very heavily to make it work the way we wanted, but MVC then and now isn’t a very modular codebase and we weren’t completely happy with the results.

From there, we got cocky and in December 2009 embarked on our own framework we called FubuMVC based on the “for us, by us” attitude because we believed that after all the bellyaching we did for years about how bad WebForms was (and it was) Microsoft gave us yet another heavily flawed framework with little input from the community that was inevitably going to be the standard in .Net.

Fast forward to today and FubuMVC is up to v1.3, spawned arguably a healthy ecosystem of extensions, and it’s used in several very large applications (fubu’s sweet spot was always larger applications).  It’s also failed miserably to attract or generate much usage or awareness in the greater .Net community — and after this long it’s time for me to admit that the gig is up.

 

Why I think it failed

Setting aside the very real question of whether or not OSS in .Net is a viable proposition (it’s largely not, no matter how hoarse Scott Hanselman makes himself trying to say otherwise), FubuMVC failed because we — and probably mostly me because I had the most visibility by far — did not do enough to market ourselves and build community through blog posts, documentation, and conference speaking.  At one time I think I went almost 2 years without writing any blog posts about fubu and I only gave 3-4 conference talks on FubuMVC total over the past 5 years.  I believe that if we’d just tried to get FubuMVC in front of many more people earlier and generated more interest we might have had enough community to do more, document more, and ground away the friction in FubuMVC faster through increased feedback.

We also didn’t focus hard enough on creating a good, frictionless getting started story to make FubuMVC approachable for newbies.  FubuMVC was largely written for and used on very large, multi-year projects, so it’s somewhat understandable that we didn’t focus a lot on a task that we ourselves only did once or twice a year, but that still killed off our growth as a community.  At this point, I feel good about our Rails-esque “fubu new” story now, but we didn’t have that in the early days and even now that freaks out most .Net developers who don’t believe anything is real until there’s a Visual Studio plugin.

I’ll leave a technical retrospective of what did and did not work well for a later time.

What I’m doing next

I turned 40 this January, but I feel like I’m a better developer than ever and I’m not really burnt out.  I tease my wife that she’s only happy when she’s planning something new for us, but I know that I’m happiest when I’ve got some kind of technical project going on the side that lets me scratch the creative itch.

I’d like to start blogging again because I used to enjoy it way back but I wouldn’t hold your breathe on that one.

We’re kicking the tires on Golang at work for server side development (I’m dubious about the productivity of the language, but the feedback cycle and performance is eye popping) and the entire Scala/TypeSafe stack.  I’m a little tempted to rewrite StructureMap in Scala as a learning experience (and because I think the existing Scala/Java IoC containers blow chunks).  Mostly though, Josh Arnold and I are talking about trying to rebuild Storyteller on a Node.js/Angular.js/Require.js/Mimosa.js/Bower stack so I can level up on my JavaScript skills because, you know, I’ve got a family to support and JavaScript quietly became the most important programming language on the planet all the sudden.

I’ll get around to blogging a strictly technical retrospective later.  Now that I’m not under any real pressure to deliver new code with fubu, I might just manage to blog about some of the technical highlights.  And if I can do it without coming off as pissed and bitter, I’ve got a draft on my thoughts about .Net and the .Net community in general that I’ll publish.

StructureMap 3.0 is Live

At long last, I pushed a StructureMap 3.0 nuget to the public feed today nearly a full decade after its very first release on SourceForge as the very first production ready IoC container in .Net.   I’d like to personally thank Frank Quednau for all his work on finally making StructureMap PCL compliant.

While this release don’t add a lot of new features, it’s a big step forward for usability and performance and I believe that StructureMap 3.0 will greatly improve the developer experience.  Most importantly, I think the work we’ve done on the 3.0 release has fixed all of the egregious internal flaws that have bothered me for years and *I* feel very good about the shape of the code.

 

What’s Different and/or Improved?

  • The diagnostics and exception messages are much more useful
  • The registration DSL has been greatly streamlined with a hard focus on consistency throughout the API
  • The core library is now PCL compliant and targets .Net 4.0.  So far SM3 has been successfully tested on WP8
  • I have removed strong naming from the public packages to make the world a better place.  I’m perfectly open to creating a parallel signed version of the Nuget, but I’m holding out for a pull request on that one:)
  • Nested container performance and functionality is vastly improved (100X performance in bigger applications!)
  • Xml configuration and the ancient attribute based configuration has been removed.
  • Interception has been completely rewritten with a much better mechanism for applying decorators (a big gripe of mine from 2.5+)
  • Resolving large object graphs is faster
  • The Profile support was completely rewritten and more effective now
  • Child containers (think client specific or feature specific containers)
  • Improvements in the usage of open generics registration for Jimmy Bogard
  • Constructor function selection and lifecycle configuration can be done per Instance (like every other IoC container in the world except for SM <3.0 😦 )
  • Anything that touches ASP.Net HttpContext has been removed to a separate StructureMap.Web nuget.
  • Conventional registration is more powerful now that the configuration model is streamlined and actually useful as a semantic model

 

 

Still to Come:

I’m still working on a new version of the StructureMap website (published with FubuDocs!), but it’s still a work in progress.  Since I desperately want to reduce the time and effort I spend on supporting StructureMap, look for it soon-ish (for real this time).

Someday I’d like to get around to updating my old QCon ’08 talk about lessons learned from a long-lived codebase with all the additional lessons from the past 6 years.

StructureMap 3 is gonna tell you what’s wrong and where it hurts

tl;dr:  StructureMap 3 introduces some cool new diagnostics, improves the old diagnostics, and makes the exception messages a lot better.  If nothing else scroll to the very bottom to see the new “Build Plan” visualization that I’m going to claim is unmatched in any other IoC container.

I’ve had several goals in mind with the work on the shortly forthcoming StructureMap 3.0 release.  Make it run FubuMVC/FubuTransportation applications faster, remove some clumsy limitations, make the registration DSL consistent, and make the StructureMap exception messages and diagnostic tools completely awesome so I don’t have to do so much work answering questions in the user list users will have a much better experience.  To that last end, I’ve invested a lot of energy into improving the diagnostic abilities that StructureMap exposes and adding a lot more explanatory information to exceptions when they do happen.

First, let’s say that we have these simple classes and interfaces that we want to configure in a StructureMap Container:

    public interface IDevice{}
    public class ADevice : IDevice{}
    public class BDevice : IDevice{}
    public class CDevice : IDevice{}
    public class DefaultDevice : IDevice{}

    public class DeviceUser
    {
        // Depends on IDevice
        public DeviceUser(IDevice device)
        {
        }
    }

    public class DeviceUserUser
    {
        // Depends on DeviceUser, which depends
        // on IDevice
        public DeviceUserUser(DeviceUser user)
        {
        }
    }

    public class BadDecorator : IDevice
    {
        public BadDecorator(IDevice inner)
        {
            throw new DivideByZeroException("No can do!");
        }
    }

Contextual Exceptions

Originally, StructureMap used the System.Reflection.Emit classes to create dynamic assemblies on the fly to call constructor functions and setter properties for better performance over reflection alone.  Almost by accident, having those generated classes made for a decently revealing stack trace when things went wrong.  When I switched StructureMap to using dynamically generated Expression‘s, I got a much easier model to work with for me inside of StructureMap code, but the stack trace on runtime exceptions became effectively worthless because it was nothing but a huge series of nonsensical Lambda classes.

As part of the effort for StructureMap 3, we’ve made the Expression building much, much more sophisticated to create a contextual stack trace as part of the StructureMapException message to explain what the container was trying to do when it blew up and how it got there.  The contextual stack can tell you, from inner to outer steps like:

  1. The signature of any constructor function running
  2. Setter properties being called
  3. Lambda expressions or Func’s getting called (you have to supply the description yourself for the Func, but SM can use an Expression to generate a description)
  4. Decorators
  5. Activation interceptors
  6. Which Instance is being constructed including the description and any explicit name
  7. The lifecycle (scoping like Singleton/Transient/etc.) being used to retrieve a dependency or the root Instance

So now, let’s say that we have this container configuration that experienced StructureMap users know is going to fail when we try to fetch the DeviceUserUser object:

        [Test]
        public void no_configuration_at_all()
        {
            var container = new Container(x => {
                // Notice that there's no default
                // for IDevice
            });

            // Gonna blow up
            container.GetInstance<DeviceUserUser>();
        }

will give you this exception message telling you that there is no configuration at all for IDevice.

One of the things that trips up StructureMap users is that in the case of having multiple registrations for the same plugin type (what you’re asking for), StructureMap has to be explicitly told which one is the default (where other containers will give you the first one and others will give you the last one in).  In this case:

        [Test]
        public void no_configuration_at_all()
        {
            var container = new Container(x => {
                // Notice that there's no default
                // for IDevice
            });

            // Gonna blow up
            container.GetInstance<DeviceUserUser>();
        }

Running the NUnit test will give you an exception with this exception message (in Gist).

One last example, say you get a runtime exception in the constructor function of a decorating type.  That’s way out of the obvious way, so let’s see what StructureMap will tell us now.  Running this test:

        [Test]
        public void decorator_blows_up()
        {
            var container = new Container(x => {
                x.For<IDevice>().DecorateAllWith<BadDecorator>();
                x.For<IDevice>().Use<ADevice>();
            });

            // Gonna blow up because the decorator
            // on IDevice blows up
            container.GetInstance<DeviceUserUser>();
        }

generates this exception.

Container.WhatDoIHave()

StructureMap has had a textual report of its configuration for quite a while, but the WhatDoIHave() feature gets some better formatting and the ability to filter the results by plugin type, assembly, or namespace to get you to the configuration that you want when you want it.

This unit test:

        [Test]
        public void what_do_I_have()
        {
            var container = new Container(x => {
                x.For<IDevice>().AddInstances(o => {
                    o.Type<ADevice>().Named("A");
                    o.Type<BDevice>().Named("B").LifecycleIs<ThreadLocalStorageLifecycle>();
                    o.Type<CDevice>().Named("C").Singleton();
                });

                x.For<IDevice>().UseIfNone<DefaultDevice>();
            });

            Debug.WriteLine(container.WhatDoIHave());

            Debug.WriteLine(container.WhatDoIHave(pluginType:typeof(IDevice)));
        }

will generate this output.

The WhatDoIHave() report will list each PluginType matching the filter, all the Instance’s for that PluginType including a description, the lifecycle, and any explicit name.  This report will also tell you about the “on missing named Instance” and the new “fallback” Instance for a PluginType if one exists.

It’s not shown in this blog post, but all of the information that feeds the WhatDoIHave() report is query able from the Container.Model property.

Container.AssertConfigurationIsValid()

At application startup time, you can verify that your StructureMap container is not missing any required configuration and generally run environment tests with the Container.AssertConfigurationIsValid() method.  If anything is wrong, this method throws an exception with a report of all the problems it found (build exceptions, missing primitive arguments, undeterminable service dependencies, etc.).

For an example, this unit test with a missing IDevice configuration…

        [Test]
        public void assert_container_is_valid()
        {
            var container = new Container(x => {
                x.ForConcreteType<DeviceUserUser>()
                    .Configure.Singleton();
            });

            // Gonna blow up
            container.AssertConfigurationIsValid();
        }

…will blow up with this report.

Show me the Build Plan!

I saved the best for last.  At any time, you can interrogate a StructureMap container to see what the entire “build plan” for an Instance is going to be.  The build plan is going to tell you every single thing that StructureMap is going to do in order to build that particular Instance.  You can generate the build plan as either a shallow representation showing the immediate Instance and any inline dependencies, or a deep representation that recursively shows all of its dependencies and their dependencies.

This unit test:

        [Test]
        public void show_me_the_build_plan()
        {
            var container = new Container(x =>
            {
                x.For<IDevice>().DecorateAllWith<BadDecorator>();
                x.For<IDevice>().Use<ADevice>();

            });

            var shallow = container.Model
                .For<DeviceUserUser>()
                .Default
                .DescribeBuildPlan();

            Debug.WriteLine("This is the shallow representation");
            Debug.WriteLine(shallow);

            var deep = container.Model
                .For<DeviceUserUser>()
                .Default
                .DescribeBuildPlan(3);

            Debug.WriteLine("This is the recursive representation");
            Debug.WriteLine(deep);
        }

generates this representation.

StructureMap 3.0 is very nearly done (no, seriously)

StructureMap 3.0, the next version of the original IoC/DI Container for .Net is almost done and now is a great time to speak up about any improvements and/or changes you’d like to have in SM3.  You can see a list of previous updates (and a shameful pattern of stopping and starting on my part) here.  To be honest, my primary goal at this moment — and why I’m able to work on this during day job hours this week — is to improve the performance of our FubuMVC or FubuTransportation applications with a secondary goal is to improve StructureMap’s diagnostic ability to explain what’s happening when things go wrong.

Big Changes and Improvements:

  • The exception messages provide contextual information about what StructureMap was trying to do when things went wrong
  • The nested container implementation is vastly improved, much faster, and doesn’t have the massive singleton behavior bug from 2.6.*
  • All old [Obsolete] 2.5 registration syntax has been removed, and there’s been a major effort to enforce consistency throughout the registration API’s
  • The original StructureMap.dll has been broken up into a couple pieces.  The main assembly will be targeting PCL compliance thanks to the diligent efforts of Frank Quednau, and that means that Xml configuration and anything to do with ASP.Net has been devolved into separate assemblies and eventually into different Nuget packages.  This means that StructureMap will theoretically support WP8 and other versions of .Net for the very first time.  God help me.
  • The strong naming has been removed.  My thought is to distribute separate Nuget packages with unsigned versions for sane folks and signed versions for enterprise-y folks
  • Lifecycle (scope) can be set individually on each Instance (stupid limitation left over from the very early days)
  • Constructor selection can be specified per Instance
  • Improved diagnostics, both at runtime and for the container configuration (still in progress)
  • Improved runtime performance, especially for deep object graphs with inline dependencies (i.e., FubuMVC behavior chains)
  • The interception model has been completely redesigned
  • The ancient attribute model for StructureMap configuration has been mostly removed
  • The “Profile” model has been much improved

What’s Next?

You can take the pre-release builds of StructureMap 3.0 out for a spin at any time from the fubu TeamCity Nuget feed at http://build.fubu-project.org/guestAuth/app/nuget/v1/FeedService.svc.  A public push could come as early as February 1st, 2014, but I’m not pushing to the public Nuget feed until the stuff in the next paragraph is done.  My thought is that the initial release will be the core StructureMap package, StructureMap.AutoMocking, and StructureMap.AutoFactory.  The new Xml configuration package and a new ASP.Net support package will come later when and if there’s a demand for that.

The issue list is getting shorter and more specific, so I’m hopeful that development is almost to a close.  I’m adding a lot of new explanatory acceptance tests as I write the new documentation (with FubuDocs!).  Frank is going to push through the PCL compliance and that’ll inevitably lead to some new complexity in how we build and create the Nuget’s in our CI builds.

I’m also going to take the new bits out for a spin with a new FubuMVC application and use that to test out what the new exception messages and diagnostics look like.  The forthcoming FubuMVC.StructureMap3 package will embed new diagnostic capabilities.

Early next week, I’m going to try to use StructureMap 3 in a bigger application at Extend Health with an eye toward measuring the new performance versus 2.6.3.

Introducing FubuCsProjFile for Project & Solution File Manipulation

tl;dr:  FubuCsProjFile is a new library from the fubu community for manipulating Visual Studio.Net project files and a new composable templating engine.

The FubuMVC community was busy last year building all new functionality for build automationdocumentation generation, and project templating.  What we haven’t done yet is actually talk about what we were doing in any kind of way that might make it possible for other folks to kick the tires on all that stuff.  This blog post and the heavily under construction website at http://fubuworld.com is an attempt to change that.

For a couple years we’ve had a couple one-off pieces of code to manipulate csproj files with raw Xml manipulation copied over some of our tooling.  When we started to get serious about rebuilding the “fubu new” functionality, we knew that we first needed a more serious way to add, query, remove, and modify items in .csproj files and .sln files.  I looked around for prior art, but found little besides the MSBuild libraries themselves which — shockingly! — did not work in Mono (wouldn’t even compile as I recall).  Fortunately, Monodevelop has very robust MSBuild manipulation code with all kinds of care taken to avoid unnecessary merge problems by maintaining line breaks and file formatting.  Because it has a permissive license, I mostly copied the csproj manipulation code out of Monodevelop and wrapped a little bit prettier object model around their very low level API.

On top of the csproj file manipulation, I added a hack-y class for adding and removing projects from Visual Studio.Net solution files and a from scratch templating engine we use heavily from our “fubu new” functionality.

We certainly don’t yet support every single thing you can do in a csproj file, but we’re already using FubuCsProjFile within Bottles to attach embedded resources, inside the forthcoming Ripple 3.0 release for querying and manipulating assembly references, and as part of the prototype functionality inside of the fubu.exe tool for generating Spark or Razor views.

FubuCsProjFile is available on Nuget under the permissive Apache 2.0 license.  We have received some reports that FubuCsProjFile has some unit tests that break on Mono (“\” instead of “/”, Unix vs. Windows line breaks, the normal stuff).  That’ll get resolved soon-ish, but that just means that I can’t claim that it will work flawlessly on Mono/*nix right now.

 

Introducing FubuDocs for “Living Documentation”

TL;DR:  The FubuMVC community is finally getting its technical documentation act together with a new tool called FubuDocs.

The Wrong Way

About 5 years ago I released StructureMap 2.5 with the idea that it would permanently lock the public registration API’s into a new, shiny fluent interface that everyone would love using from now on.  As part of that release, I wrote comprehensive documentation with lots of embedded code samples painstakingly copied into the static html files and published a pure HTML website. Then I started using StructureMap 2.5 in daily work, found out that I hated using the new fluent interface, and immediately changed the public API’s in subsequent releases to smooth out the usability problems.  Unsurprisingly, I never got around to updating the now defunct documentation code samples.  

Moreover, the documentation that I did write wasn’t always helpful to users because the organization of content on the site did not make sense to them and they weren’t always able to find the right content.

Fast forward several years and the FubuMVC community has built a tremendous number of potentially useful libraries, features, and frameworks that nobody knows about mostly because I’m nearly allergic to writing documentation.  To give all our hard work an actual chance to be successful, Josh Arnold and I envisioned and built a new tool for creating and publishing living documentation we fittingly called FubuDocs (the FubuDocs documentation at this link is created and published with FubuDocs itself).

FubuDocs Highlights

  • The documentation lives side by side with the real code
  • We “slurp” sample code directly out of the real code and automated tests so the sample code cannot get out of synch with the current API to avoid the headaches I had earlier with StructureMap documentation.
  • Heavily inspired by readthedocs.org, FubuDocs determines the navigation structure and navigation page elements for you based on the files in your documentation project
  • You can run a FubuDocs project website interactively using the fubudocs tool distributed as a gem.
  • The fubudocs interactive mode exposes a topic manager tool you can use to extend, reorder, and modify the documentation outline.
  • You can use a combination of Markdown syntax and custom html elements to author content
  • Exports the final content to static HTML (we are just publishing to GitHub Pages).
  • It’s “skinnable” — in theory, works on my box, nobody else has tried that yet

 

In a later post, I’ll talk about how we have automated the publishing and versioning of technical documentation within our continuous integration infrastructure.

Presentations in NDC London and Skillsmatter in December

Back in the old days I used to get aggravated at folks that asked to blog on CodeBetter and then do nothing but post about their upcoming conference talks, but now I’m apparently that guy now.

Anyway, I’m going to be in London the first week of December for NDC London and a night at Skillsmatter.  At NDC I’m giving a talk on my organization’s experiences with automated testing and some of the technical strategies we use to get better results and more reliable tests against very enterprise-y systems.  Don’t be fooled by the word “testing” in the title, this is a very technical talk with no hint of non-coding Agile Coach “all you need is good communication” naiveté and very little process mumbo jumbo.

I’m also going to be playing straight man to Rob Ashton and Rob Conery’s snark filled shenanigans in a debate over testability on the .Net platform versus Node.js.  While many folks have already written me off (the .Net side), just remember that the Harlem Globetrotters would be no fun without the Washington Generals around.

Most excitedly for me, I’m getting to go speak Thursday night, Dec. 4th at Skillsmatter on several of the OSS projects I work on and with.  I’ll…

  • Discuss FubuMVC’s approach to modularity and how my organization exploits this to cleanly isolate feature development in large applications.
  • Demonstrate the much improved “fubu new” story for mix and match generation of a full code trees
  • Briefly explain why I think RavenDb could be one of the best things to ever happen to .Net development and how we’re using it inside FubuMVC applications and our test automation harness.
  • Show how we’ve used Katana to create an efficient development server and an option for embedding FubuMVC in any .Net process.
  • Explain why in the world we went to the effort of building Ripple (http://fubuworld/ripple) to smooth out our early issues with using Nuget for complex dependency management.
  • Talk about some of our new tools and tricks for distributed development including the new FubuTransportation service bus. I’ll also show how we’re using multi-AppDomain support with our Bottles modularity framework to make debugging and testing easier for distributed development.
  • The 3.0 release of StructureMap is close to being released, and while IoC containers are a dime a dozen now, I’d like to share some of the hard lessons I’ve learned about usability, non-insane exception messages, performance, and useful diagnostics over the past decade of developing and supporting StructureMap.
  • And just in case you thought xUnit tools were a completely solved problem, I’d love to talk about why I’m so enthusiastic about the new Fixie testing tool (https://github.com/plioi/fixie)

This is my first time to spend any kind of significant time in London and I’m looking forward to catching up with old friends on your side of the pond and the inevitable bouts of “man, I didn’t recognize you from your twitter avatar.”

 

FubuMVC at Monkeyspaces

I will be joining a very impressive group of speakers at this year’s MonkeySpace conference in Chicago to give a couple talks related to FubuMVC:

Exploring the FubuMVC and Bottles Ecosystem

I think that the combination of FubuMVC with Bottles represents the very best modularity solution in all of .Net and that it’s competitive with anything else out there.  In this talk I’m going to try to back up that claim with a quick demonstration of rapidly building out your application infrastructure with the existing ecosystem of drop in FubuMVC plugins (bottles). I’ll pull back the curtains and talk about the architectural decisions that made all the modularity possible and what we learned along the way.

Dependency Management in .Net OSS Development

The Fubu project ecosystem is big and growing.  For the past couple years we’ve used a combination of Nuget and TeamCity to quickly push build products and dependencies from upstream projects to downstream consumers. We ran into a lot of technical problems and limitations with just about everything we’ve ever tried to do. In this talk I’ll show you the new ripple tool (ripple is sort of to Nuget as Bundler is to gems) we’ve built and adopted to smooth out consuming and publishing Nugets across the 60 odd fubu-related repositories.  I’ll also show some concrete examples of how standardization has smoothed out the process.

For myself, I’m looking forward to Sebastien’s ReST talk, seeing what’s going on with OWIN, and making sure that every poor Microsoft attendee who crosses my path knows exactly how much pain strong naming + Nuget causes us.

I’ll be looking forward to meeting new people at MonkeySpace and catching up with friends I haven’t seen in quite a while (and getting out of the Texas summer heat for a couple days).

See you there.

Introducing FubuMVC.CodeSnippets for living documentation

TL;DR:  FubuMVC and its related projects are finally getting some documentation, and the FubuMVC.CodeSnippets library is a big part of the “how” we’re trying to make the docs easier to write and maintain

Once upon a time there was a man who worked on an open source tool named “StructureMap.”  This man spent an inordinate about of time on his 2.5 release, crafting a comprehensive set of documentation in static html as part of that release.  Upon making the long awaited release, some unpleasant things happened:

  1. Many people didn’t like or just couldn’t derive any value out of the documentation website because of the way it was organized
  2. This man quickly realized from his own usage that many of the new API’s were awkward to use and he immediately added alternative API’s to make StructureMap 2.5+ usable
  3. It wasn’t easy to edit the big pile of html and copy/pasted code samples, making the effort even more painful — so the docs and the actual API wildly diverged and didn’t help the poor man handle user questions

Since I’d strongly prefer not to be that guy ever again, we’re putting some effort toward using “living documentation” techniques for FubuMVC, Storyteller, and StructureMap 3 to make it as easy as possible to keep the documentation in synch with the various frameworks as they evolve.  As part of that goal, we’re using the FubuMVC.CodeSnippets (check out the link, there’s real documentation developed with FubuDocs) library to “slurp” sample code snippets right out of the live code during the automated builds.  This way we can simply reuse unit test code and bits of example code running in the CI.  If the real code changes, the sample code and the unit tests would have to change too or the CI build breaks.

In a nutshell, the idea behind FubuMVC.CodeSnippets is to just add some comments into your code marking the boundaries of a named “snippet” like so:

// SAMPLE: snippet-name

// C# code in the middle.

// ENDSAMPLE

In a FubuMVC view, you can just say “I want to display snippet named ‘snippet-name'” and the view helper for code snippets will add the raw code in a <pre> tag and use prettyprint to color code the code.