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

November 2008 - Posts

  • A Gentle Quickstart for StructureMap 2.5

    The most general question I get with StructureMap is “how do I get started?”  Personally, I’d recommend that you first get comfortable with some concepts and the basic patterns of Dependency Injection and Inversion of Control first.  Assuming that you’re already familiar with those concepts, or you’d really rather skip the pedantry and jump right into concrete code, the first thing to do is go download StructureMap and jump into usage (then come back to the patterns and pedantry). 

    Some Salient Facts:

    • The latest release is 2.5.0.0, available for download on SourceForge at http://sourceforge.net/projects/structuremap
      • The only DLL that you need for doing basic Service Locator and/or Dependency Injection is the StructureMap.DLL file.
    • There is a google group for StructureMap support at http://groups.google.com/group/structuremap-users?hl=en
    • StructureMap is released under the Apache 2.0 license, meaning that you can use it in any application or even modify the source in any way you see fit without restriction.
    • StructureMap is actually the oldest, original IoC tool for .Net with the first production release coming in June of 2004
    • I’m no longer the only person maintaining StructureMap
    • The source code is accessible here via Subversion in case you’re curious.  No credentials are required to access the source code.
    • Right now, StructureMap 2.5 will run on .Net 3.5 only.  I will most likely NOT be backporting the new version to 2.0 because of extensive usage of 3.5 features like Expressions
    • I swear that StructureMap 2.5 will run in medium trust on .Net 3.5 – but please post any problems that you do find with medium trust.
    • A 2.5.1 release is planned for the first week of December with bug fixes, a few new little features, Mono support, and a Silverlight-ready version (it’ll be a subset of the main library).

     

    The Simplest Possible Usage of StructureMap

    Your interaction with StructureMap is going to mostly consist of two activities:

    1. Asking StructureMap for an instance of a service or dependency (the easy part)
    2. Registering “what” and “how” StructureMap should build or find those requested services (the tedious part, but it’s gotten much better over the years)

    In our system we use a service called “IValidator” to exercise validation rules on our domain model objects (I talked about the approach here).  By default, we want any consumer of the IValidator interface to use the concrete class named Validator.  Since we use StructureMap for resolving dependencies and services, we need to first tell StructureMap to use Validator anytime somebody asks for an IValidator.  You configure StructureMap by initializing the container with this code below:

        public static class ContainerBootstrapper

        {

            public static void BootstrapStructureMap()

            {

                // Initialize the static ObjectFactory container

                ObjectFactory.Initialize(x =>

                {

                    x.ForRequestedType<IValidator>().TheDefaultIsConcreteType<Validator>();

                });

            }

        }

    Now that that code is called somewhere in the application initialization, we can get an IValidator object from StructureMap like in this sample code by calling ObjectFactory.GetInstance<IValidator>():

        public class ClassThatGetsAnIValidator

        {

            public void SaveObject(object objectToSave)

            {

                // Go get the proper IValidator from StructureMap

                IValidator validator = ObjectFactory.GetInstance<IValidator>();

     

                var notification = validator.Validate(objectToSave);

                if (notification.IsValid())

                {

                    // save the object

                }

            }

        }

    That’s it, your first usage of StructureMap.  No messy Xml configuration, no attributes scattered through your code, just a couple lines of bootstrapping code.   Of course, if that’s all StructureMap did, it wouldn’t be worth your time to download it.  Let’s look at a bit more advanced example.

     

    Primitive Arguments

    I actually like to use StructureMap as a generic configuration tool (which was actually its original purpose).  Let’s say you’re moving to the data access code.  You come up with some sort of Repository pattern class like this:

        public interface IRepository

        {

            void Save(object target);

        }

     

        public class Repository : IRepository

        {

            public Repository(string connectionString)

            {

                // set up the persistence infrastructure using the connectionString

                // from the constructor argument

            }

     

            public void Save(object target)

            {

                // save the object

            }

        }

    The Repository class needs to be supplied with the “connectionString” in its constructor.  No problem, just set up the value of the constructor argument in the bootstrapping:

                ObjectFactory.Initialize(x =>

                {

                    x.ForRequestedType<IRepository>().TheDefault.Is.OfConcreteType<Repository>()

                        .WithCtorArg("connectionString").EqualTo("a connection string");

     

                    // Or, since it's smelly to embed a connection string directly into code,

                    // we could pull the connection string from the AppSettings

                    x.ForRequestedType<IRepository>().TheDefault.Is.OfConcreteType<Repository>()

                        .WithCtorArg("connectionString").EqualToAppSetting("CONNECTION-STRING");

                });

    With the bootstrapping out of the way, when we ask StructureMap for an IRepository in this code:

                var repository = ObjectFactory.GetInstance<IRepository>();

    StructureMap will look up the “CONNECTION-STRING” value in the AppSettings portion of the App.config file, and use that string value to invoke the constructor function of the Repository class, then hand back that new Repository object.  Woo hoo.  We can build an object that doesn’t depend on anything, and we can build an object that needs some strings in its constructor function.  How about objects that need other non-primitive objects?

     

    Auto wiring

    In the code samples above, I used StructureMap as a Service Locator in the ClassThatGetsAnIValidator.SaveObject() method.  Typically, you’ll try to minimize the number of service locator usages in your system to a bare minimum (I found 8 in my current system, but I think I’ll find a way to prune half of those later).  Most of the value of an IoC tool is in automatically doing Dependency Injection.  I’m working with the new MVC framework at the moment, so it’s a handy sample.  Let’s say that we have a Controller class for a typical CRUD screen.  That Controller class will generally need to interact with both validation services and the data access functionality of the Repository.  Here’s a representative Controller class:

        public class SomeScreenController : IController

        {

            private readonly IRepository _repository;

            private readonly IValidator _validator;

     

            // SomeScreenController depends on both IRepository and IValidator

            public SomeScreenController(IRepository repository, IValidator validator)

            {

                _repository = repository;

                _validator = validator;

            }

     

        }

    So let’s get StructureMap set up for this SomeScreenController class:

                ObjectFactory.Initialize(x =>

                {

                    // Set up the IValidator

                    x.ForRequestedType<IValidator>().TheDefaultIsConcreteType<Validator>();

     

                    // Set up the IRepository

                    x.ForRequestedType<IRepository>().TheDefault.Is.OfConcreteType<Repository>()

                        .WithCtorArg("connectionString").EqualToAppSetting("CONNECTION-STRING");

                });

    You’ll notice that we didn’t make any explicit configuration for the SomeScreenController class, but yet we could now call:

               var controller = ObjectFactory.GetInstance<SomeScreenController>();

    and StructureMap will happily create a new instance of the SomeScreenController class by invoking its constructor and passing in a new Validator object and a new Repository object created with the connection string from the App.config file.  We didn’t need to tell StructureMap how to construct SomeScreenController because:

    • StructureMap can look at the constructor function of SomeScreenController and see that it depends on IValidator and IRepository
    • StructureMap “knows” about the default way to create and return an IValidator and an IRepository

    This feature is known as “auto wiring,” and all the mainstream IoC containers support this to some extent or another. 

     

     

    What to do when things go wrong?

    StructureMap, and any other IoC tool for that matter, is configuration intensive – which means that their will be problems in that configuration.  We’re all moving to more convention based type registration – which means that more stuff is happening off stage and out of your sight, making debugging the configuration even trickier.  Not to worry (too much), StructureMap has some diagnostic abilities to help you solve configuration problems.  The quickest tool is to ask a Container object or ObjectFactory (which is just a static wrapper around a Container) “what do you have?” with the Container.WhatDoIHave() method like this below:

                var container = new Container(x =>

                {

                    x.ForRequestedType<IValidator>().TheDefaultIsConcreteType<Validator>();

     

                    x.ForRequestedType<IRepository>().TheDefault.Is.OfConcreteType<Repository>()

                        .WithCtorArg("connectionString").EqualToAppSetting("CONNECTION-STRING");

                });

     

     

                Debug.WriteLine(container.WhatDoIHave());

    Which would spit out this text into your output window:

    ===========================================================================================================
    Configuration Sources:
    
    0)   Registry:  StructureMap.ConfigurationExpression,StructureMap
    
    
    ===============================================================================================================================================================================================================================================================================================================================
    PluginType                                                                                                                Name                                                                                                 Description                                                                                     
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    ShadeTree.Validation.IValidator, ShadeTree, Version=0.8.0.0, Culture=neutral, PublicKeyToken=null                         ShadeTree.Validation.Validator, ShadeTree, Version=0.8.0.0, Culture=neutral, PublicKeyToken=null     ShadeTree.Validation.Validator, ShadeTree, Version=0.8.0.0, Culture=neutral, PublicKeyToken=null
    Built by:  StructureMap.Pipeline.BuildPolicy
    
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    StructureMapSample.IRepository, DovetailCRM.IntegrationTesting, Version=0.9.0.0, Culture=neutral, PublicKeyToken=null     27fdf13e-8adc-4f8f-9f53-cf7b35ada80c                                                                 Smart Instance for StructureMapSample.Repository                                                
    Built by:  StructureMap.Pipeline.BuildPolicy
    
    ===============================================================================================================================================================================================================================================================================================================================

    which is admittedly, not the prettiest looking thing in the world.

    You can also “assert” that the configuration for a Container or ObjectFactory is complete by calling the Container.AssertConfigurationIsValid() method like this sample below:

                var container = new Container(x =>

                {

                    x.ForRequestedType<IValidator>().TheDefaultIsConcreteType<Validator>();

     

                    x.ForRequestedType<IRepository>().TheDefault.Is.OfConcreteType<Repository>()

                        .WithCtorArg("connectionString").EqualToAppSetting("CONNECTION-STRING");

                });

     

     

                container.AssertConfigurationIsValid();

    This method will analyze every thing in the Container configuration and:

    1. Look for any missing constructor or mandatory setter arguments
    2. Look for any unknown dependency types
    3. Look for any errors in the Xml configuration (if you’re using Xml configuration)
    4. Try to build each and every type and named instance in the configuration – i.e. this is a complete, but relatively expensive operation
    5. Run any environment tests configured with the [ValidationMethod] attribute (a feature that is unique to StructureMap as far as I know)

    The previous sample is a valid configuration, but let’s look at an invalid configuration.  Let’s omit the configuration of the “connectionString” constructor argument for the Repository class and try AssertConfigurationIsValid():

            [Test]

            public void lets_see_if_the_container_is_valid()

            {

                var container = new Container(x =>

                {

                    x.ForRequestedType<IRepository>().TheDefault.Is.OfConcreteType<Repository>();

                        //.WithCtorArg("connectionString").EqualToAppSetting("CONNECTION-STRING");

                });

     

     

                container.AssertConfigurationIsValid();

            }

    When I run the unit test above, this is part of the output:

     

    Build Error on Instance '73b7f21b-bbfd-462c-854d-5b2a2f98ba50' (Smart Instance for StructureMapSample.Repository)
        for PluginType StructureMapSample.IRepository, DovetailCRM.IntegrationTesting, Version=0.9.0.0, Culture=neutral, PublicKeyToken=null
    
    StructureMap.StructureMapException: StructureMap Exception Code:  205
    Missing requested Instance property "connectionString" for InstanceKey "73b7f21b-bbfd-462c-854d-5b2a2f98ba50"

     

    which again, isn’t the prettiest thing in the world, but it does tell me that the “connectionString” argument is missing for the Repository class.  After seeing this output, I think that this output and error wording will get improved in an upcoming release.

     

     

    Why are you still rolling your own IoC tool?

    Something that bothers me pretty is when I see bloggers frequently say that “StructureMap/Windsor/Ninject/Unity/Spring.Net/Autofac” is way too heavy for my project, so I just rolled my own.  Why?  Why would you do that?  Bootstrapping StructureMap for the very simplest cases, i.e. the only cases you can handle with the “roll your own IoC container in 30 lines of code solution,” takes 1 line of code for the call to ObjectFactory.Initialize() plus another line of code for each individual type.  

     

    Related Links:

    By no possible means was this a complete guide to using StructureMap or IoC tools in general.  Try these other links for more on StructureMap:

  • Agile .Net Developer Opportunity in Atlanta

    My friend and former colleague Paul Gale is looking to build a strong Agile .Net team in Atlanta.  If you're interested, here are the details from the man himself:

    • I am looking to build a team of up to 6 (including myself) experienced agile .NET developers by the end of 2009.  However, we're trying to hire in a more opportunistic mode, i.e., if a decent developer is available we'll take a look at them, rather than spread it out just to fit a hiring program.
    • The company is called Cint. We're HQ'd in Stockholm (It will be easier to explain the exact relationship between the Atlanta dev group and our Stockholm dev group to candidates directly).
    • Candidates should have a strong background in TDD ideally in an XP environment. We'll be pairing too.
    • More to the point this is NOT the type of position where someone who fancies trying their hand at TDD, say, should apply. You will be tested!  We're looking for strong players who will bring their game with them.
    • Skills aren't everything though; they must be a good social fit for the team that's already in place.
    • We're currently renting space in downtown Atlanta. However, we're looking to move very soon to Alpharetta, GA close to G400.  (Local folks will know what that means. Others can ask).

    See http://www.cint.com/Cpx/About.aspx for more details.

  • I'll be back to the land of the living next week

    Call this an open apology, with an unfortunately true excuse.  I'm pathetically behind in email correspondance and answering questions on the StructureMap board (I was sick, then I had QCon, plus I'm just plain slow to begin with).  I have to go in for a minor surgery tomorrow morning that's going to knock me out for a couple days.  I'll get caught up as soon as I'm up to fiddling with the computer.

  • A Train of Thought – QCon San Francisco 2008

    I’ve been at QCon San Francisco most of the week, and I think I can say that content wise, it’s the best “eyes forward” conference I’ve ever attended.  I’m finished with all my speaking and relatively satisfied with how it went.  All the talks were filmed and will appear on InfoQ.com at some point.

    As always, everybody I talk to is working on a more interesting project than I am, but that’s just a case of the grass always being greener on the other side of the hill.  I don’t have much at the minute, but here’s a start on a wrapup.  I’ll catch up on StructureMap requests and emails over the weekend for all of you waiting on something from me.

     

    The Highlights

    • Martin Fowler and Rebecca Parsons talk on reconciling enterprise architects with Agile processes.  I think they made a very good case for using incremental delivery mechanisms and the transparency that Agile can provide to aid architects.  Buuuuuuttttttt, in order for their recommendations to work, I think that large companies will have to dramatically change their attitudes towards the people that build software.  Hands on skills and application architecture skills have to be held in much more regard by many companies than it is today.
    • Seeing some Google Web Toolkit in action at a talk from Alex Moffat (fellow Austinite it turns out).  I’ve always blown off the tools that try to hide Javascript, but I’m intrigued by GWT.
    • The Volta talk.  There was a lot of (highly justified) dubiousness in the room, but it’s interesting.
    • Jay Fields DSL talk. 
    • Don Syme showing how 30-40 lines of C# could be accomplished in 2 lines of F#
    • Tim Bray’s talk on alternative storage devices.  It’s possible, possible I say, that you and I may build a significant system someday that does not run against a relational database.

     

    Just Be Thoughtful

    In my Evolution of a Developer post a couple weeks ago, I had a question in the comments:

    So how do you recommend training an eager kid out of college with little or no experience to get through these steps quickly?

    In typical me fashion, I didn’t get a response together in a timely manner, but I will now.  Be thoughtful about your work.  Experience is the greatest teacher, but not all experience is created equal.  When you do software projects or assignments, and especially something challenging or big, reflect upon it later.  What would you do differently?  Why?  Why did you choose to do it the way that you did for that matter?

    I had the pleasure of attending one of Kent Beck’s talks here at QCon.  It wasn’t anything revolutionary or even informative to be honest, but what I saw was one of the masters of our craft simply reflecting over how he made design decisions.  I think it’s a good example to follow.

    From experience though, do watch out for the “second system syndrome.”

    Favorite Exchange of the Week

    • Me:  Argh!  You should have told me that you were going to show me VB code!
    • Rod:  Relax, dude.  It’s just English.  We don’t use those hieroglyphics that you do (C#).

     

    Big Systems

    Someday, I’d really like another opportunity to build a really big, highly scalable type of application again.  But it’s much more important to my sanity to permanently stay out of big companies.  Oh well, I guess I’ll just settle for working in a very pleasant environment with people that I like.

  • Thoughts on the Decline and Fall of Agile

    If you haven't already, go give this post from Jim Shore a read.

    I've seen a lot of commenters on this post so far, and their thoughts generally mirror my own.  You can't take the "desserts" of Agile practices like working incrementally or the all important adaptive planning and scheduling without quite a bit of engineering practice vegetables.  You wanna work adaptively instead of the ol' fashioned plan driven method?  Fine, but you've got to make that adaptability safe.  You need rapid feedback cycles to know when you're getting off the rails (customer demos, TDD, Continuous Integration, automated acceptance tests, static code analysis or some sort of equivalent).  You need to take steps that make continuous design methods safe and effective (simple design, a constant attention to design fundamentals like the SOLID principles, and an intolerance for technical debt).  And your team needs to be retrospective about its work to make adaptions as they become necessary.

    In the early days, XP was roundly criticized because every practice only seemed to be safe due to the existence of the other practices.  Take one out, and the others weren't that great by themselves.  I think that's more or less a fair criticism, but my response is simply to adopt, and effectively apply, everything you need to make Agile development successful.  You can't just pick and choose the easy things.  If you take something off the old XP practice recipe, you probably need to find an analogue solution to add something else back into your practices.  Regardless of which practices and how you do those practices, there are project needs that have to be filled (planning, quality assurance of some sort, feedback cycles, etc.).

    Of course, it's always going to be easier to get it wrong than right, but that's why we're paid the big bucks.

  • Some Reading on Essence vs. Ceremony

    In both my next MSDN article and a bit of my QCon talk I'm exploring the topic of "Essence vs. Ceremony" applied to .Net architectures.  Along the way, I reread this gem from Stuart Holloway:

    Ending Legacy Code Within Our Lifetime

    and discovered this from Neal Ford:

    Ceremony vs Essense

     

    Stu & co at Relevance are primarily a Ruby shop, but I highly recommend their blog for anyone interested in software craftsmanship.

  • At QCon next week

    Next week I'm presenting the Joys and Pains of Long-Lived Codebase's at QCon San Francisco.  In my 5+ years of evolving the StructureMap code far away from its original intentions I've learned some hard lessons.  In my talk I'll share some experiences and thoughts on:

    • Choosing solid abstractions for your design, and recognizing when abstractions no longer fit the requirements
    • The design principles that allow for evolving a design -- and the painful consequences of not following those principles.  More importantly, how to retrofit those qualities in order to make design changes possible.
    • How can you most effectively use TDD or BDD to enable architectural changes -- and the mistakes I made with TDD that hampered design changes
    • Constructing a framework and how our expectations of a framework have changed in the last half decade
    • Creating API's for other developers

     

    I've been looking forward to this for months.  I hope to see some of you there.  I'll try to blog as much as possible about it as soon as I get back. 

     

    P.S.  Just ignore all the "No Fluff, Just Stuff" gurus that may or may not be speaking at the same time as me.  I may give away some sort of door prize just to get some attendees to my talk;)

  • Don't Check in Spike Code...

    ...into the trunk.

    Just like the title says, do NOT check “spike” code into the source control trunk.  When you do an exploratory spike, you’re generally throwing good coding practices completely out the window.  You’re on a focused mission to “figure out how this gosh durned thing is supposed to work.”  The code that you write in a spike probably sucks anyway. 

    Do spike whenever you’re unsure how to work with some new library or technology or to try out a new object structure – but put that code in a branch.  As soon as the spike has achieved its purpose, put that code aside, and write all new code in the trunk using TDD and your normal coding standards.  You know, the coding and design standards that you've adopted as a team because you think those standards lead to sustainable quality.  But Jeremy, I could just retrofit some unit tests around the spike code and call it good!  Maybe, but you better ask yourself, am I really going to put decent tests around this code?  Retrofitting unit tests never results in the same quality of tests as real test first development.  Besides, as I said earlier, spike code generally sucks anyway;-)

  • Evolution of a Developer (in regards to DI/IoC)

    I’m putting together a new quickstart for StructureMap tonight.  In looking over my notes, I found a draft from earlier this year where I was trying to argue the value proposition of an IoC container.   I’m scrapping most of that post, but I wanted to share some thoughts on dependencies and structure in software designs.  My advice is to get yourself to bullet number 4 below in order to make your design, unit testing, and coding efforts more efficient – regardless of whether or not you use an IoC container.

    I think the evolution of a developer's mindset towards structuring applications goes something like this:

    1. Just gotta make this work.  There isn't any separation of concerns.  Code responsibilities tend to fall wherever the developer happened to be in the code when he or she realized they needed something (what I refer to as stream of consciousness coding).  For myself in the late nineties, this trait manifested itself as popping open an ADO connection and grabbing an ADO recordset anytime, and anywhere, that I needed some data in the middle of a long ASP page.  I've worked in a couple different development environments and read code in twice that many since, but in my experience nothing leads to a big ball of mud faster than the combination of ASP Classic and developer carelessness.  The code worked, and that's definitely something, but large amorphous code modules tend to be difficult to troubleshoot, maintain, and modify.  Plus, they can easily lead to duplication because code isn't structured for reuse.
    2. The next stage is learning to put things in their place.  The developer has progressed enough to internalize the value of separating concerns into cohesive modules.  The developer is thoughtfully asking the question to himself or herself "where should this code go?"
    3. Wait, I've separated my concerns, but everytime I change one module changes ripple into other modules.  Each concern seems to know too much about the details and functions of other concerns.  Now we start to worry about being able to change how the system behaves by making isolated changes that impact the fewest number of modules as possible.  To make this happen we need to make sure the different modules are loosely coupled from each other.  At this point we begin to make much more use of interfaces and abstractions to reduce the coupling between modules.  We also strive to build modules that do not incorporate any knowledge of the other modules that the first module depends on.
    4. The developer is fully cognizant of dependency relationships in his or her codebase.  At this point we're ready to consider using Dependency Injection and Inversion of Control to both further encourage loose coupling and exploit the seams in our application.
    5. The developer finally learns some completely new way of building software and feels like they've started all over again at phase #2.

    I think the leap from #1 to #2 is huge chasm that many developers will fail to cross in their careers, but every following transition becomes easier. 

     

    The following is a partial repeat of an older post, but I think it applies here:

    Coder to Craftsman

    When people first learn how to write code they necessarily focus on just making the code work, with little or no thought for style or structure, and certainly no thought for the future.  Any particular piece of code tends to land wherever the coder happened to be working when they realized that they needed that piece of code -- or wherever the RAD wizards felt like dropping the code. 

    I think there is an inflection point where a coder mindlessly spewing out code transforms into a thoughtful software craftsman capable of creating maintainable code.  That inflection point happens the day a coder first stops, lifts his/her nose out of the coding window, and says to him/herself "where should this code go?"  That might also lead to questions like "how can I do this with less code?" or "how can I write this to make it easier to understand?" or even "how can I solve one problem at a time?"  The rest of a developer's career is spent pursuing better and better answers to the question "where should this code go?"

  • My best days as a coder

    Last time I was negative and sarcastic, so this time I want to be positive.  My best days as a coder were:

    • When I used to write Shadow IT apps for my engineering team, anytime I wrote something that eliminated a lot of grunt work was a very happy day.
    • I got stuck as a noncoding architect in possibly the worst IT shop in the country, but the biggest joy ever was the day they released the new "Responsibility Matrix" and my team realized that our "System Architect" role was not responsible for one single intermediate deliverable.  That's right, zero responsibility.
    • The day that I first "got" ReSharper
    • The day the ReSharper 4.0 finally became stable
    • The day that I first "got" jQuery
    • The day that my first big system went live -- and worked on the first big transaction.
    • The iteration when a previously troubled project suddenly righted itself and the coding became easy
    • The day I toured a factory and saw my software running at all the receiving doors
    • The day Chad & I decided to quit our previous job
    • The day last month when our new rules engine & rules DSL ran flawlessly for the first time after a 6 week coding sprint
    • The time my friend got an award from the business users in appreciation for the new application we built together. 
    • Any single day I get a complement on StructureMap or somebody writes me to say my blog helped them with something
    • My first ThoughtWorks away day.  If you want to learn to be a good developer, the easiest way to get there is to interact with good developers. 
  • Upcoming Posts

    I had tonight reserved as my night to do all those blog posts I've promised folks, but I ended up moving boxes all night and I'm crashing instead.  For all of you that have made requests, in the next couple days I hope to churn out:

    • A Gentle StructureMap Quickstart (very basic)
    • Using StructureMap to bootstrap NHibernate (w/ Fluent NHibernate and our particular flavor of Repository / Unit of Work)
    • Convention Based Type Registry in StructureMap
    • Introduction to the Application Controller Pattern for Desktop Apps (by request, but it amounts to "Jeremy gets serious about the book")
    • My KaizenConf wrapup
    • and I owe Glenn Block several posts.  I'll get around to it.  I promise.

    Now, off to bed.

  • What's your worst day as a coder?

    Yesterday I was switching our test automation driver layer from WatiN to Selenium RC (Firefox / Chrome / Opera support and I was livid with the COM errors from IE in WatiN).  I think I'm glad that we made the switch, but it took quite a bit of trial and error to bend Selenium RC to my will.  That and something else I read today got me to pondering the worst days I've ever had as a coder trying to make unfamiliar or confusing technology work.  My list is something like this:

    • Using a CLOB or BLOB datatype in Oracle.  I've done it several times, but it never seems to get any more pleasant
    • Getting a custom authentication scheme to work with x509 certificates.  Shudder.
    • The day that a client developer hosed our CVS repository
    • The day that our project, the project that was going so marvelously with the team that was starting to gel, was shelved on a management whim
    • The day a month before go live when the BA finally saw fit to tell me about the other half of the requirements document that no one had told me about previously
    • The days that followed "here's how to use our homegrown ORM"
    • The days that followed "you must use our standard architecture for..."
    • Writing queries against a custom Active Directory schema.  Ended up ditching AD a month later and just put all the user information in the database.  The nice, predictable, familiar database.
    • Any number of days doing test automation with NFit or FitNesse
    • Almost any day fighting with Legacy code, but that shouldn't really count
    • The day and a half I spent making StructureMap work with open generic types a couple years ago. 
    What's yours?
  • How to design your data connectivity strategy

    I'm scurrying at lunch to finish reviewing some architectural guidelines for the P&P group (I'll be done today, I promise).  I stumbled across a section with the same title as this blog post.  I'll answer the question concisely:

    Pull an existing persistence tool off the shelf, make sure you understand it, and code, code, code!  Persistence coding is a commodity in this day and age, so just use and existing tool and get on with your project.  It's extremely unlikely that there's any business advantage to writing data access code by hand when there are so many existing tools out there.  I'll repeat this little gem one last time, if you're writing ADO.Net code by hand, you're stealing from your employer or client. 

     

  • Time to slow down the Oslo hype

    This quote about Oslo & SOA is over the top:

    Because the software infrastructure that supports your business model is not based on some gobbledygook that only the guy with the pocket protector and horn rimmed glasses understands. The software that supports your business model is based on models and these models are aligned with business capabilities that bring value to the organization and these models are also aligned with standards based, interoperable and reusable webservices that represent your software infrastructure. 

    Puh-leeze.  Only uber-"pocket protector and horn rimmed glasses" guy is going to be capable of utilizing Oslo effectively to create that clean business facing language in the first place.  And again, only the geeky programmer is going to have the slightest clue about how that spiffy new DSL is actually translated into real functionality.  Having a "Model" that's just a lump of data isn't all that useful.  Something has to actually make the "Model" be executable, and I nominate the guy with the pocket protector.

    Oslo potentially == a new way to integrate external DSL's into the .Net ecosystem != non-programmers "writing" software.  Let's set our sights just a little bit lower.  Just being able to write code that closely reflects the business domain is a huge win.  Getting business experts able to write the actual code, even in a DSL, isn't going to happen.

    C'mon here.  I'm very interested in Oslo too, but I can't see any way in which Oslo is a game changer. 

  • There’s nothing worse…

    …than being a developer who leaves the office with a pernicious coding problem unsolved – mostly due to working with a technology I’m not familiar with.  I spent a couple hours at the end of the day trying to make some new test automation code work to no avail.  Leaving work without solving the issue just leaves a very sour taste in my mouth.  I fired up my computer and took another hour and a half to finally solve my problem this evening.  I wasted a night, but at least I feel calmer heading into the bedtime hours.

More Posts Next page »

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