Choosing the Constructor Function in StructureMap without Attributes

A longstanding complaint with StructureMap is that the way StructureMap selects a constructor function can only be overridden with an attribute.  Using attributes is now frowned upon, and other times is impossible.  StructureMap 2.5.2 (the version in the trunk that, knock on wood, I get released no later than Saturday) introduces a quick programmatic way to select the constructor function using the magic of Expressions.  This is an excerpt from the new StructureMap documentation I’m working up.  It will be much more readable on the website (next week hopefully):

 

 

StructureMap has always allowed you to override the constructor choice with an attribute, but increasingly, many people are unwilling to use attributes in their code for infrastructure concerns.  Other times you may want to override the constructor choice of a class that you don’t control.  Either way, it would be useful to select the constructor function used by StructureMap to build a concrete code in the Registry DSL.  The syntax to do just that is shown below:

Let’s say that you have this class (from the unit tests):

    public class ClassWithTwoConstructors

    {

        public ClassWithTwoConstructors(int age, string name)

        {

        }

 

        public ClassWithTwoConstructors(int age)

        {

        }

    }

By default, StructureMap would choose the “greediest” constructor.  In this case, it would be the constructor that takes in “age” and “name.”  To force StructureMap into using the other constructor, use the SelectConstructor() method on the Registry:

            var container = new Container(x =>

            {

                x.SelectConstructor<ClassWithTwoConstructors>(()=>new ClassWithTwoConstructors(0));

                x.ForConcreteType<ClassWithTwoConstructors>().Configure

                    .WithCtorArg(“age”).EqualTo(34);

            });

The argument to the SelectConstructor is an Expression of type Expression<Func<T>> where T is the concrete class.  StructureMap parses the Expression to find the constructor function in the Expression object.

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.
This entry was posted in StructureMap. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    Thank you Dennis

  • Dennis

    Nice! I’ve really come to despise attributes. For the reasons you mentioned already. thank you for adding this feature… and for that matter.. the entire Structuremap tool.

  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    @John,

    Yeah, and that’s how I feel about it too, but just like the BuildUp() thing, it’s an imperfect world and sometimes you’ve gotta adapt to it.

  • John

    “Another question is: isn’t the existence of multiple constructor functions a bit of a smell?

    That’s exactly where my question was heading :)

  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    @John,

    Every so often you hit some class where you want to inject something in testing scenarios, but not in the normal IoC/production mode.

    I found one example in our code where we have an object that can be created with existing state in one constructor, but when we retrieve it from SM, we want to use a default no-arg constructor to build it with no existing state.

    Sometimes you may just want to control ambiguity between multiple constructors.

    Another question is: isn’t the existence of multiple constructor functions a bit of a smell?

  • John

    Jeremy, while this is a nice feature, can you tell me why one would use this? If I’m injecting dependencies into my class via the constructor, it’s normally because they are dependecies and they are required. Why would have a constructor with less parameters?

  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    @Dirk,

    I might be exaggerating a little bit, but there is a definite backlash against frameworks or tools that require you to mark up your own code with configuration attributes. Putting attributes in your code for something like ORM mapping or IoC directives is creating a tighter coupling to those tools and adding noise code where you might not want it.

  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    @BjartN,

    The syntax in this post would handle that situation.

    SelectConstructor(() => new SomeClass(new Dog());

    Would pick out the constructor function that takes a Dog.

  • BjartN

    What if I have two constructors with a single complex object like:

    public SomeClass(Person myPerson){}

    public SomeClass(Dog myDog){}

    I know the Spring.NET DI container solves this using the name of parameter which in your case would map to something like …WithCtorParamName(“myPerson”)

    Is there any way of doing this currently ?

  • Dirk

    “Using attributes is now frowned upon”

    When did this happen?

  • http://http:blogs.lessthandot.com Christiaan Baes

    I only asked for it once ;-).

    But WOOHOO.

    Is this VB.Net compatible? ;-) (joke).