Reusability vs. RYO
Every so often, a topic brushes by my RSS feeds that I have to jump into and comment on. The latest foray is a conversation between Chris Holmes, Jeremy Miller, and Oren Eini. It started with Oren and a post about not particularly caring for what the Microsoft Patterns & Practices guys are producing (EntLib, CAB, SCSF, etc.) and ballooned here, here, and here. Oren started down the path that CAB (and other components produced by P&P) was overly complex and unnecessary. I'll focus on CAB but there are other smatterings of things from EntLib here. The main points Oren was getting across (if I read him correctly) was lack of real world applications backing what P&P is producing and overly complex solutions for simple(r) problems. Oren put together his version of the policy injection block (a recent addition to EntLib) in 40 minutes. Last night I was reading Jeremy Millers response and needed to chime in as I'm very passionate about a few things, namely Agile software development and CAB.
I'll be the first to admit that CAB is complex. EntLib is large. There is a lot there. As Chris said this morning in what I think was an excellent response to the entire discussion, CAB for example is not just about building maintainable WinForm apps. I like CAB as it gives me a bunch of things and they all work together in a fairly harmonious way. EventBroker is a nice way to message between views and keeping the views separate; ComandHandlers allow me to hook up UI elements indirectly to code to execute them; the ActionCatalog let's me security trim my commands (and in turn my UI); and the implementation of the MVP pattern using views lets me write presenter tests and keep my UI thin. This all makes me feel good. Did it take me a while to get here? Absolutely. I've spent the better part of a year learning CAB, EntLib, ObjectBuilder, WorkItems, and all that jargon but it's no different than learning a dozen different 3rd party libraries. I simply chose the MS path because it was there and everything was in one neat package. If you packaged up Castle, NHibernate, StructureMap, and others together in a single package maybe I would have chosen that path (and is there really two different paths here? I use both tools together anyways).
Oren's defense is around the fact that he (and Jeremy) follow the guideline of evolving a framework from your application needs, not building one (like what the P&P guys have done). Okay, that's fair but at some point you have to stop building things over and over again. So when does your own work become a framework that you reuse? Is it as lean and mean as what you want it to be. Sure, you can put together the basic needs of an IoC in half a day (half a day Bil time, 40 minutes Oren time) but it's the just the beginning. It serves the need you have today and the problems you might be facing right now. I would argue that if you took something like StructureMap and evolved it to handle scenarios that you're not dealing with today, that you would be starting to build your own implementation of EntLib.
We all want lean software that does the job however I subscribe to the mentality that if you leverage something else (aka not reinventing the wheel) then do so as long as it doesn't come at a cost higher than doing it yourself. That's a hard decision to make as you don't want to get too predictive on what the future may hold (do we need logging, security, etc. in the future?) but you gauge your response based on current affairs and what feels best. It's more of an art than a science. When I first looked at CAB I thought it was huge, but once I sat down to grok the pieces and how it all fit together, it made sense. EntLib and CAB do include everything and the kitchen sink and you do need to get past the learning curve, but in the end it's a good collection of tools that you can have in your toolbox. Unfortunately it's not something I could introduce at a conference or User Group session and describe the entire stack in an hour, so I tend to avoid showing off applications and concepts using it as it just turns into a discussion of what [SmartPart] means instead of the main goal like describing MVP which I can do with my own code.
Is EntLib/CAB/etc. doing too much maybe? Perhaps but then if I choose the 3rd party elements I want and wire them together to suit my needs, what kind of Frankenstein have I built in the progress? When I look at CAB holistically, there's a lot there but it's not a bad implementation. I don't think Oren or Jeremy are saying the P&P guys did a bad job on in, they just choose to evolve their own solutions using a minimalist approach. I'm all for that. It's very TDD-like. When I build systems I start by writing single tests against my domain and only doing what I need at the time (the YAGNI principal). However at some point you end up with a very rich domain, hundreds (or thousands) of unit tests, dozens (hundreds) of classes and methods, and a lot of functionality. I argue that is in fact what EntLib and CAB have become. They're rich, re-usable tools that do a lot but frankly you can still use what you need. Maybe you'll deploy all the EntLib assemblies with your application and only use the logging feature, but so what? As an example, I had to implement NHibernate in an application recently to apply persistence to my domain. When I ran some db unit tests, I found out that I need the NHibernate assemblies, log4net, and an assembly from Castle to make it work. Disk space is dirt cheap so having the extra there means nothing (except a few extra seconds of download time).
I'll cite Rocky and his excellent CSLA.NET as an example. It's a large framework, lots of classes, lots of functionality. That's what frameworks are about. However while I like what Rocky's done and he's had great success at it, I don't subscribe to the approach he took. I'm not a fan of the ActiveRecord pattern and don't like how business objects are tied to data implementation (even if there's a level of abstraction there). I simply cannot use CSLA with DDD. Is the framework a bad product? No way. Would I recommend it to others? Absolutely. Would I use it myself. Nope, but it's a good piece of software and I wouldn't discount it.
CAB follows similar concepts as it's big and ugly in some places (like ObjectBuilder). Sure I could use Castle to do better (real) dependency injection, but if I don't buy into the MS song and use CAB and EntLib to it's full extent I end up with bits and pieces of goo all over the place. Like I mentioned with NHibernate, I needed to deploy log4net as it needs it, even if I didn't turn on that feature. At least with EntLib, if I'm not using security for example I don't need to deploy the security module. In my case now, I have EntLib logging deployed and now I've got a second logging system deployed because NHibernate dragged it along for the ride. Eventually I could have a really ugly monster on my hands with copies of Castle, StructureMap, CAB, EntLib, NHibernate, log4net, and who knows what else all living (hopefully) together in happy existence. I don't want that.
CAB gives me most of what I need (except O/R mapping and persistence) so for me I leverage as much as I can from CAB and EntLib and fill in the gaps with things like NHibernate for persistence. I could use EntLibs database factory but then I'm rolling my own DAL and that's not a path I want to take, so I choose to ignore the EntLib database component. The nice thing is that I don't have to deploy it so as long as my code doesn't call it, I'm golden.
As Jeremy put it, the P&P guys are a good thing as they're out there getting the Agile word out to many more people that we can. While they do produce large(r) tools, frameworks, and components that include perhaps more complexity that you need at the time at the end of the day, you'll probably end up using it. IMHO I'm happy with what CAB and EntLib provide. Could I get the same functionality from the other alteratives? For sure, however I would probably be writing more code to wire things together than I would with CAB. For that reason, I like what the P&P guys do and look forward to the future as to how they'll evolve hoping these kind of discussions will help adjust their path towards a better end game for all of us.