CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Jeremy D. Miller -- The Shade Tree Developer

Under the hood and working with .Net, TDD, Software Design, and Agile Stuff

August 2008 - Posts

  • The State of IronRuby on the ALT.NET Podcast

    Mike apparently took some time off from being a new Dad to gather up the latest news on IronRuby.

    The State of IronRuby

     


  • A Train of Thought – August 24th, 2008 Edition

    Thank God I don’t have my old 3 hours a day of commuting into Manhattan, but I needed to spit out some little blog postlets in more than 140 characters at a time, so I present to you the latest Train of Thought.  Opinionated blathering ahead, comments are always open at the bottom.

     

    Don’t Overreach in Your Designs

    One of my older posts on The Last Responsible Moment and another post on evolutionary design were recently linked on some of the DZone/DotNetKicks sites and got some traffic.  I got some comments and emails to the effect of “we did evolutionary design and it bit us in the ass with all that refactoring and rewriting.”  Maybe, but let’s talk about how to do evolutionary design in a way that minimizes outright rework.  From my experience, the worst rework results from choosing elaborate abstractions upfront that turn out to be harmful.  The analogy that I like is trying to walk on slippery ground.  Anybody who’s walked across an icy patch or a muddy field this knows that the way to do it is to keep your feet as close to your center of gravity as possible by taking short steps.  If you take a big step you’re much more likely to slip and fall.  Design is the same way.  Bad things happen when you allow your design thinking and abstractions get ahead of your development and requirements.

    We’re doing evolutionary design, and yes we have had to rewrite some functionality when we’ve found shortcomings in the design or simply found a better way to do it.  I would attribute the worst example of avoidable rework on our project to overreaching with some infrastructure outside of user stories.  We’re using the new ASP.Net MVC framework, and we didn’t like the way that it handles (or really doesn’t handle) the “M” part of the MVC triad.  We had one of those conversations that starts with “wouldn’t it be cool if…” and ended with one or both of us spending days of architectural spiking on an approach for screen synchronization – before we created our first web page.  We created the idea of a “ViewModel” that would represent screen state and help us to move data between the web page form elements and our Domain Model objects.  We wrote a very elaborate code generation scheme to automate a lot of the grunt coding.  As soon as we started to work on our first couple web pages we quickly realized that much of our ViewModel infrastructure was unnecessary or just plain wrong.  We effectively rewrote the ViewModel code generation in a simpler way and got on with the project.  Since then, we’ve extended the ViewModel code generation to add new behaviors on an as needed basis, but we haven’t had to rewrite any of it.

    Just to head off the comments, I didn’t know about the BindingHelperExtensions in the MVC at the time (shame on me).  I don’t regret rolling our own infrastructure at all because I don’t think that BindingHelperExtensions is adequate, but I wish we’d played it a little smarter and put off the ViewModel code generation until we had a couple working pages to point out the real patterns.

    What I’m trying to say here is to avoid speculative abstractions and fancy patterns outside of feedback from the real features and needs of the system.  It’s relatively painless to extend simple code for more elaborate usages than its original intentions, but it hurts to throw out or change elaborate code.  You can hedge your design bets by (almost) always starting simple.

     

    Enabling Evolutionary Design

    So, how do you do evolutionary design without incurring a lot of rework?  Here’s my recipe:

    • Worry a lot about cohesion and coupling as you work. 
    • Follow the Open/Closed Principle
    • Follow the Single Responsibility Principle
    • Use TDD or BDD for low level design.  First because it does more to ensure good cohesion and coupling on a class by class basis than any other technique, but also because the automated unit testing coverage left behind enables changes in the code to be cheaper in many cases.  Regression testing is a cost and risk associated with changing code is a considerable road block to making design improvements midstream.  If you reduce that cost and risk, evolutionary approaches are a lot more attractive.  That test coverage is one of the ways that TDD/BDD is more valuable a practice than merely applying some unit tests after the fact to strategic areas of the code.

    From an old post:

    One way to think about TDD is an analogy to Lego blocks. The Lego sets I had as a child were the very basic block shapes. Using a lot of little Lego pieces, you can build almost anything your imagination can create. If you buy a fancy Lego set that has a single large piece shaped like a pirate's ship, all you can make is a variation of a pirate ship.

    In that context I was talking about TDD, but I feel like the analogy holds very true for doing evolutionary design effectively.  Composing your system of small Lego pieces that can be rearranged is much better than using big monolithic pieces of code that are more likely to be modified later.

    In the end, it really amounts to just design things well, all the time.  Unsurprisingly, I think that teams with strong software design skills are best equipped to do evolutionary design.

     

    On Software Factories

    Last week I was at an Open Spaces event in Colorado with a very diverse group of folks in a session that rambled around until “Software Factories” came up.  I stated, and not for the first time, that Software Factories are often Big Design Upfront dressed up in sexier new clothes.  I definitely think the software factory idea can work (with Ruby on Rails as exhibit A), but I think the activity of defining elaborate project and class templates upfront is risky or at least unoptimal.  A project team’s is going to have much less willingness to reconsider designs if design changes require changing the software factory templates.  To me, software factory techniques will succeed if and only if it’s easy to modify the factory automation guidance as the team works and learns more about their system.

    My other point with software factories was that I think micro code generation (live templates, file templates, ReSharper tricks, scaffolding, etc.) where the developer is in complete control has a much better chance of succeeding than the elaborate factories that try to generate most of the application for you. 

     

    Opinionated Software

    Ruby on Rails introduced “Opinionated Software” into the common lexicon, but it’s been around for a while.  I think that my team is gaining some advantages from our design’s “opinions,” but what if you don’t like the opinions of your chosen framework?  Take CSLA.Net as an example.  I want absolutely nothing to do with CSLA.Net because I think its basic model is severely flawed, but I bet that it’s providing a lot of value for many teams.  That value is largely because CSLA.Net has firmly engrained “opinions” about how almost every common development task should be done.  I can’t use CSLA.Net, and a lot of the Microsoft tooling for that matter, because I don’t agree with the “opinions” baked into that tooling.  I’ll happily build my own infrastructure to support the way that *I* feel software should be created, or go around a piece of infrastructure I don’t agree with.  Heck, the MVC framework isn’t even released and we’ve already considerably diverged from its opinions.  Other developers will simply go with the flow of whatever tooling that their using and invest time into learning the idioms of that particular tool and not waste time questioning that tool. 

    I think this comes down to a question of “go with the flow or change the course of the river.”  I’m a “change the course of the river” to the optimal path kind of guy, but I frequently wonder if it would be better to just give up and go with the flow.

     

    TypeMock is only a Bullet of Ordinary Composition

    I was out of pocket last week at a little open spaces event, so I missed most of the latest Twitter and blogging flareup of the TypeMock question.  I’ll repeat my opinion that there’s nothing inherently wrong with TypeMock itself, but I think that the rhetoric from TypeMock proponents is often harmful to the greater discussion of software design and practices.

    TypeMock might be a better mocking framework than Rhino Mocks or Moq, but it does NOT change the fundamental rules of mock object usage.  Just because you can use TypeMock to mock a dependency doesn’t mean that it’s the right thing to do.  Let’s remember some of my rules of mock object usage:

    • Don’t ever try to mock chatty interfaces like ADO.Net or anything related to HttpContext because the effort to reward ratio is all wrong and you can never read those tests anyway. 
    • Be extremely cautious of mocking interfaces that you do not understand. 

    The only thing that TypeMock changes is *how* the mock object is introduced into the code being tested.  If you really think that having separate interface definitions plus Dependency Injection is hard, then yeah, use TypeMock (an assertion that I would obviously dispute in this age of auto wiring, auto mocking containers, ReSharper, and convention driven configuration of IoC containers).  Just remember a couple things please:

    • Mocking in general isn’t going to be an effective technique with classes that aren’t cohesive or have a lot of semantic coupling with their dependencies.  In other words, interaction testing with any mock object is going to be painful with badly written code.  TypeMock simply doesn’t change that equation.  I’ve heard TypeMock put forward as a solution for unit testing legacy code.  In theory yes, but the reality that I’ve found is that interaction testing inside Legacy Code is an exercise in pain.  Most legacy code (and I’m using the Feathers definition of legacy code here) has very poor internal structure and poor separation of concerns.  Exactly the kind of code that you shouldn’t bother using interaction testing on.  I’d instead recommend surrounding Legacy Code with more coarse grained integration tests to preserve behavior first, then trying to modify the internal code to a better structure before writing fine grained unit tests.  Yes, it is possible to use TypeMock to “unit test” typical legacy code, but those tests would almost automatically be the type of overspecified unit tests that cause more harm than good.  The problem with legacy code is often the structure of the code more than the fact that it doesn’t have any unit tests.
    • Yes, you can unit test the class in question that news up its own dependencies and calls static methods, but you still have a very tight runtime coupling to those dependencies and the static method calls.  Regardless of your ability to unit test the class in question, that tight coupling can often be a problem.  Your ability to reuse those classes is compromised by the tight dependencies.  Your ability to practice evolutionary design is compromised because of the tight coupling.  Remember that Dependency Inversion and Inversion of Control have other benefits than just unit testing.

    I think the TypeMock proponents are too focused on unit testing in a way.  I firmly believe that code that can’t be efficiently unit tested is almost automatically bad code (to me, testability == productivity).  However, code that can be unit tested isn’t necessarily good.

    To recap, I don’t think there’s anything wrong with TypeMock per se, but I think that much of the TypeMock proponent’s rhetoric is irresponsible.  Just because TypeMock *can* do something, doesn’t mean that doing that something is a good idea. 

     

     

    In Tribute to George Carlin

    I couldn’t think of 7, and it’s a couple months late for a Carlin tribute, but here’s my list of the words or phrases that are henceforth banned from appearing in my blog or presence (starting right now).  Almost no conversation is going to be useful if it includes one of these words:

    • Mort – Apparently Microsoft is now referring to the developer formerly known as “Mort” as “Pragmatic Developers.”  Puh-leeze.  Everybody in the world thinks that they’re pragmatic, but yet we disagree on many significant directions in the best way to build software.  I was dead set against ALT.NET getting renamed “Pragmatic.Net” for the same reasons.  I gotta say though, “Pragmatic Developer” is much less a pejorative than “Mort” became and the typical “Joe Schmoe Developer who builds LOB apps at General Motors” line you hear from Microsoft employees.
    • Entity Framework – At least until there’s something new to say.  I’m liking that my attention lately has been on the advance of Fluent NHibernate instead of worrying about a tool that I’m very unlikely to use in the next 2-3 years.
    • Stored Procedures – I’ve seen nothing to change my opinion about sprocs for several years (good for edge cases and utility database scripts, bad everywhere else, i.e. 95%+ of the time I think sprocs are unnecessary)
    • TypeMock
       
    • “Vietnam of Software Development” – Most  overblown and misused analogy this side of Software as Construction.
    • “Software as Construction” – I worked on the engineering side of construction projects measured in the 100’s of million dollars and even billion dollar+ projects (and this was in the pre-W days when the USD was more than paper money), plus I worked for my father building houses as well.  I feel perfectly qualified to say that the “Software as Construction” analogy is an extremely poor fit.  Software as Manufacturing is better, but I bet that somebody will write a rant about that comparison in the next couple years.
    • Foo Considered Evil – It’s a cliche now
    • “Cargo Cult” – used as a magic talisman to win any argument, regardless of whether the use of the phrase is applicable or not.
    • “Your Emperor has no Clothes” – see above
    • “Jumped the Shark” – see above
    • “You should just use whatever is best for your project” – The intellectual equivalent of empty calories
    • “You’re just being dogmatic!” – Lamest way to try to win an argument.  Basically, this is code for “I’m pissed that you don’t agree with me so I’m just going to call you names and declare victory, so there!”
    • “You can just Refactor it later” – You can write simplistic code upfront and say you’ll refactor it later to eliminate duplication or handle more complicated cases as those cases arise, but you don’t write bad code on purpose.  You certainly don’t use Refactoring as an excuse to just not think about design.
    • “We’re refactoring” when the team really means “we’re rewriting that code altogether.”  There’s no such thing as a big refactoring.

     

     

    Okay, I’m done.  Your turn:

  • “SmartInstance” in StructureMap 2.5

    From the feedback on the StructureMap Google group, Chad and I have hashed out a new Fluent Interface expressions for explicitly defining constructor arguments and setter values (I still think Setter Injection is a design smell, but I’ve been vociferously voted down).  The problems in the current version is that SetProperty() is overloaded to mean either setter or constructor arguments.  The underlying mechanisms in StructureMap stores the information the same way, but the API was causing real confusion.  So, to alleviate that confusion and also to utilize some of the new .Net 3.5 goodness, I present the new language:

    Defining primitive constructor arguments -- WithCtorArg(“name”).EqualTo(“value”)  or  WithCtorArg(“name”).EqualToAppSetting(“key”)

            [Test]

            public void DeepInstanceTest_with_SmartInstance()

            {

                assertThingMatches(registry =>

                {

                    registry.ForRequestedType<Thing>().TheDefault.Is.OfConcreteType<Thing>()

                        .WithCtorArg("name").EqualTo("Jeremy")

                        .WithCtorArg("count").EqualTo(4)

                        .WithCtorArg("average").EqualTo(.333)

                        .SetterDependency<Rule>().Is(x =>

                        {

                            x.OfConcreteType<WidgetRule>().SetterDependency<IWidget>().Is(

                                c => c.OfConcreteType<ColorWidget>().WithCtorArg("color").EqualTo("yellow"));

                        });

                });

            }

     

    Defining primitive setter properties – just uses a Lambda expression that will be applied to the object as soon as it’s built.  Intellisense and compiler safety are good things, so you might as well use it.  StructureMap now supports optional setter injection, meaning that you no longer need to do the [Setter] attributes in the concrete classes.  If you specify the value of a setter, StructureMap will use that value regardless of whether or not the [Setter] property exists.  The same rule applies to non-primitive setter dependencies.

    instance.SetProperty(x => x.Name = "Jeremy")

     

    Overriding Constructor Dependencies – Only when you want to override the auto wiring behavior.  I’ve chosen to use a Nested Closure for defining the child instance of the IWidget constructor argument below.  You could also replace x.Object() with x.OfConcreteType<T> or x.ConstructedBy(Func<T>) or other options inside the Is() method.  I chose this solution because I thought it would make it easier to guide the user to the possible options.

    instance.CtorDependency<IWidget>("widget").Is(x => x.Object(widget))

     

    Overriding Setter Dependencies – Setter dependencies (non-primitive types) are specified much like constructor arguments.  Your options are to say:  .SetterDependency<T>().Is(whatever) or .SetterDependency<T>(x => x.Setter).Is(whatever).

                    registry.ForRequestedType<Thing>().TheDefault.Is.OfConcreteType<Thing>()

                        .WithCtorArg("name").EqualTo("Jeremy")

                        .WithCtorArg("count").EqualTo(4)

                        .WithCtorArg("average").EqualTo(.333)

                        .SetterDependency<Rule>().Is(x =>

                        {

                            x.OfConcreteType<WidgetRule>().SetterDependency<IWidget>().Is(

                                c => c.OfConcreteType<ColorWidget>().WithCtorArg("color").EqualTo("yellow"));

                        });

     

    Explicitly defining an array of dependencies – I get into this scenario with configuring business rules.  Let’s say you have a class that depends on an array of some other type of service.  That syntax looks like:

                    registry.ForRequestedType<Processor>().TheDefault.Is.OfConcreteType<Processor>()

                        .WithCtorArg("name").EqualTo("Jeremy")

                        .TheArrayOf<IHandler>().Contains(x =>

                        {

                            x.References("Two");

                            x.References("One");

                        });

     

    or

     

                IContainer container = new Container(r =>

                {

                    r.ForRequestedType<Processor>().TheDefault.Is.OfConcreteType<Processor>()

                        .WithCtorArg("name").EqualTo("Jeremy")

                        .TheArrayOf<IHandler>().Contains(x =>

                        {

                            x.OfConcreteType<Handler1>();

                            x.OfConcreteType<Handler2>();

                            x.OfConcreteType<Handler3>();

                        });

                });

     

    In this case, I was lazy and made no distinction between constructor arguments and setter arguments.

     

     

    Adding additional instances of a given type – Sometimes you’re adding more than one instance of a given service type to StructureMap.  You may be fetching by ObjectFactory.GetNamedInstance<T>(name) or by ObjectFactory.GetAllInstances<T>().  Either way, this syntax will work.

                    registry.ForRequestedType<IService>().AddInstances(x =>

                    {

                        x.OfConcreteType<ColorService>().WithName("Red")

                            .WithCtorArg("color").EqualTo("Red");

     

                        x.Object(new ColorService("Yellow")).WithName("Yellow");

     

                        x.ConstructedBy(() => new ColorService("Purple")).WithName("Purple");

     

                        x.OfConcreteType<ColorService>().WithName("Decorated").WithCtorArg("color").EqualTo(

                            "Orange");

                    }));

     

     

    Thoughts?  Comments?  I should say here that StructureMap 2.5 will be about 95% backwards compatible with the existing FI, so no worries about converting.

     

     

     

    It’s funny, but I generally think that with few exceptions the Constructor Injection is the preferable approach, but I continuously read that the Java guys are exactly the opposite.  To each his or her own I guess.

  • Continuous Improvement in .NET Software Development

    The website is up for the "Continuous Improvement in .Net Software Development" conference has been posted at http://kaizenconf.com/.  It's a bit different in scope than ALT.NET Seattle in that there will be free workshops before the open spaces event over the weekend. 

    I've been instructed to say that the information on the website is of yet incomplete, so watch that website for more information.

  • The Null Pattern is a Good Thing

    That's all I've got to say this morning.  Check it our here:  http://en.wikipedia.org/wiki/Null_Object_pattern

  • It's time for IoC Container Detente

    I was perusing the session list for ALT.NET Canada this morning (sorry I couldn't make it guys) and saw this session title that reflects something I've had quite a few conversations about this year.

    Building extensible frameworks leveraging framework consumer selectable IoC containers.

    As long as we're going to work in static typed languages, it's a major advantage to achieve extensibility and pluggability by utilizing an existing Inversion of Control container.  I'll make the statement that starting with an existing IoC tool makes framework construction far simpler and cheaper than it was before.  The problem with that is that there are multiple IoC containers out there, and tying your framework to any of those containers is bound to irritate a big swath of people. 

    When we were deciding between Ruby on Rails, the ASP.Net MVC, and MonoRail for our project architecture in June, I dismissed MonoRail in small part because I didn't want to be forced to use Windsor as our IoC tool (for some reason). We're perfectly content with the MVC framework at the moment*, but after reading through the MVC code and the way that they pass around dependencies through the myriad SomethingContext objects, I think the MVC team could streamline their own code quite a bit by using an IoC tool to resolve dependencies.  Now, that brings up a contentious issue, which container would they use?  The answer is that they can't use any specific container.

    When I was building the initial code that has became Fluent NHibernate there were a couple places where I needed to use an IoC container to resolve NHibernate objects and deal with configuration.  I obviously chose StructureMap and buried a couple hard references to ObjectFactory.GetInstance<T>() in the code.  The coupling to StructureMap doesn't particularly concern me, but when the code first went public, Nate Kohari (author of Ninject) lamented on Twitter that the tool was coupled to StructureMap.

    So, to make it safe for both Nate and myself to use the IoC of our choice, what I'd really like to see is a common interface to represent the very baseline functionality of an IoC container so that we could build and release frameworks that utilize an IoC container without forcing a particular choice of tool onto the development teams. A couple people are already going down the path of abstracting an IoC container with one off solutions.  Off the top of my head I can think of at least three:

    • MVCContrib
    • Caliburn
    • Whatever boring name that Prism is now called (and I owe P&P a reference implementation of Prism with StructureMap.  I'm getting there)

    All of these frameworks have a more or less similar interface for the container, then an adapter for most of the major IoC tools.  I'd like to propose, and I'm not the first, that a new Service Locator abstraction be added to the .Net Framework itself as a first class citizen and publicized a little bit so framework builders can take advantage of a common interface.  I'd like to start a new petition to make this little, itty bitty work be a part of the MEF project within Microsoft.  All I think it needs to do is provide an interface with:

    1. GetInstance<T>()
    2. GetInstance<T>(name)
    3. GetAllInstances<T>()
    and leave the registration completely alone because it's so radically different from one tool to another.  Then, give us something like Thread.CurrentPrincipal for a wellknown place to put the container.



    *Honestly, we've replaced a fair amount of the MVC framework with our own stuff, but that's a post for another day.  The best thing about the MVC is that it's so small and fairly modular, so it's relatively easy to swap in your own "special sauce" to embed conventions and more opinionated structures.
  • Dovetail is looking for a Junior to Midlevel Developer

    Edit 8/22/2008:  We had a good response to this and other postings, and we've filled the position.  I'm sorry, but I don't expect us to grow again anytime soon.

     

    The take away from this is that we have an open slot for a junior developer, and we’d like to fill that slot with somebody who wants to grow.  Josh and I were talking yesterday about our experiences coming up and how we effectively received zero mentorship.  I think our Dovetail team is positioned to be a great place for developers to grow in skill and experience.  For that matter, Austin is a great place to be a .Net developer because of the richness of our developer community.

    I’m just going to copy Chad’s announcement:

    Work for one of the most progressive development shops in the US. This is an opportunity to work with some of the leaders in the .NET/C# space including Jeremy Miller and our recent addition, Joshua Flanagan – both senior designers and architects with tons of experience. We’re building a new software product line using pioneering practices and technologies, such as:

    • Test-driven development
    • Continuous integration
    • Behavior-driven design
    • Domain-driven design
    • HTML, CSS, Javascript
    • ASP .NET MVC
    • C# 3.0, .NET 3.5, Visual Studio 2008
    • SQL 2005
    • NHibernate 2.x
    • LINQ2NHibernate
    • StructureMap
    • WatiN
    • StoryTeller, FIT

    Who we’re looking for || Dovetail Software is staffing a new team for an innovative software project. We’re looking for junior- to mid-level software developers with demonstrable C# (preferably .NET 2.0 or later) and HTML/CSS experience (not necessarily ASP.NET, just web development in general). Any experience with test-driven development or automated unit testing in general is a huge plus.  Also, participation in the community (attendance of events, avid blog reader + commenter, or maybe you even have a blog yourself) will put you firmly in the running for this position. We’re looking for people that believe learning and continuous improvement are primary responsibilities of a software developer. We’re hiring motivated people for a terrific opportunity with a team of recognized .NET and agile community leaders.

    Our development methodology || We are an Agile shop (Scrum/XP). We work in short iterations, not long crushing release cycles. We have a collaborative relationship with our customers. We write tests before we write functional code to clarify our design intentions. We keep the build clean. We work in an environment that maximizes communication to minimize the volume of spec documents. We build software that can effectively respond to change. We use open source tools where appropriate, and Microsoft tools where they make sense. We have executive support and visibility all the way up to the owner of the company.

    About Dovetail Software || Serving companies since 1995, Dovetail Software develops CRM products for global 1000 enterprises. Our product, Dovetail CRM, is a comprehensive customer service and support, logistics management, customer self service, and knowledge management suite. Dovetail is a small company with big customers and great benefits for its employees. Our outstanding compensation package includes company-assisted health, dental, and life insurance, matching 401k, and more.

    About Austin || Placing second in the Large Cities Creativity Ranking, Austin is recognized as a city with a thriving music scene, ethnic and cultural diversity, endless outdoor recreations, and a great nightlife. It’s a nationally recognized center for technology innovation—home to 3,200 tech companies with 98,000 employees.

    Email us and tell us why you’d make a great addition to our team: tech-jobs@dovetailsoftware.com

  • Dovetail welcomes the Flim Flam Man

    Chad & I have gotten tired of being an old married couple, so we've brought in reinforcements.   Today we welcomed Josh Flanagan (developer extraordinaire and StructureMap committer) to the Dovetail team.  Welcome aboard Josh!

  • Shame Card 2008

    Our new shame card:  If you break the build somebody writes you up on Twitter where the world can mock you.



    No, we don't really do this, but... 

     

  • Say Hello to Fluent NHibernate

    I'll let James Gregory do the introduction for Fluent NHibernate here.  I think this project has a lot of potential to dramatically reduce the difficulties teams face when working with NHibernate.  The initial focus is on a fluent interface mechanism for NHibernate configuration, but I'm hopeful that it grows into the easiest way to use NHibernate

    In a nutshell, what if...

    • You could configure NHibernate with Intellisense and zero, I said zero, Xml?
    • You had some easy tooling for testing out NHibernate mappings?
    • You could make significant shortcuts in your persistence mapping by setting sensible project conventions once and only once?
    • You could start with a reference architecture for a Repository?
    • You had sample "recipes" for bootstrapping NHibernate with the common IoC tools?

     

    The guys doing Fluent NHibernate are going gangbusters getting this thing ready to go.  Nice job guys.

     

More Posts

Our Sponsors

Proudly Partnered With


This Blog

Syndication

News

All opinions expressed here constitute my (Jeremy D. Miller's) personal opinion, and do not necessarily represent the opinion of any other organization or person, including (but not limited to) my fellow employees, my employer, its clients or their agents.

About Me

"Best Of" Compendium

StructureMap (Dependency Injection for .Net)

StoryTeller (Supercharged Fit)

Build your own Cab

TestDriven

MVP