Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

AutoWiring in StructureMap 2.5+

Getting the StructureMap docs a going.  Here’s an excerpt:

 

 

The best way to use an IoC container is to allow “Auto Wiring” to do most of the work for you.  IoC Containers like StructureMap are an infrastructure concern, and as such, should be isolated from as much of your code as possible.  Before examining Auto Wiring in depth, let’s look at a common anti pattern of IoC usage:

IoC Container Anti-Pattern

One of the worst, but sadly  most common, usages of an IoC container is shown below:

        // This is the way to write a Constructor Function with an IoC tool

        // Let the IoC container “inject” services from outside, and keep

        // ShippingScreenPresenter ignorant of the IoC infrastructure

        public ShippingScreenPresenter(IShippingService service, IRepository repository)

        {

            _service = service;

            _repository = repository;

        }

 

        // FAIL!

        // This is the wrong way to use an IoC container.  Do NOT invoke the container from

        // the constructor function.  This tightly couples the ShippingScreenPresenter to

        // the IoC container in a harmful way.  This class cannot be used in either

        // production or testing without a valid IoC configuration.  Plus, you’re writing more

        // code

        public ShippingScreenPresenter()

        {

            _service = ObjectFactory.GetInstance<IShippingService>();

            _repository = ObjectFactory.GetInstance<IRepository>();

        }



Example

Typically, you’ll try to minimize the number of Service Locator (Container.Get*****) 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 feature to some extent or another. 


StructureMap’s Policies for Auto Wiring

By default, as long as an object is being created by invoking its constructor function, StructureMap will try to create/resolve/find an object for each non-primitive dependency in the requested concrete type.  If StructureMap doesn’t “know” how to find a requested dependency, it will throw an exception.  By design, StructureMap cannot auto wire primitive arguments like strings and numbers.  The Auto Wiring can be overriden by explicit configuration (this might actually be easier with Xml configuration):

                registry.InstanceOf<Rule>()

                    .Is.OfConcreteType<WidgetRule>()

                    .WithName(“TheWidgetRule”)

                    .CtorDependency<IWidget>().Is(i => i.TheInstanceNamed(“Yellow”));

In the example above, the IWidget dependency of the WidgetRule class is overriden.


Object Identity within a Single Request

Within a single object request, StructureMap will only create a single object for a single Instance configuration.  What that means in effect is that if two or more objects in a single request need the same dependency, those two objects will get the exact same instance of that dependency.  Let’s immediately jump into code to demonstrate this.

This auto wiring policy was intended for objects that need to be shared by lots of other objects.  A common example of this is some sort of DataContext class:

        public class DataContext

        {

            private Guid _id = Guid.NewGuid();

 

            public override string ToString()

            {

                return string.Format(“Id: {0}”, _id);

            }

        }

Now, let’s say that I have a hierarchy of classes that all need to work on a DataContext:

        public class Class1

        {

            public Class1(DataContext context){}

 

            public override string ToString()

            {

                return string.Format(“Class1 has Context: {0}”, _context);

            }

        }

 

        public class Class2

        {

            public Class2(Class1 class1, DataContext context) {}

 

            public override string ToString()

            {

                return string.Format(“Class2 has Context: {0}\n{1}”, _context, _class1);

            }

        }

 

        public class Class3

        {

             public Class3(Class2 class2, DataContext context) {}

 

            public override string ToString()

            {

                return string.Format(“Class3 has Context: {0}\n{1}”, _context, _class2);

            }

        }

When you request an object of Class3 with a call to Container.GetInstance<Class3>() like this:

        [Test]

        public void demonstrate_session_identity()

        {

            var class3 = container.GetInstance<Class3>();

            Debug.WriteLine(class3);

        }

The output is:

Class3 has Context: Id: 3abe0330-e94f-48a3-b8c3-56d278eea07f
Class2 has Context: Id: 3abe0330-e94f-48a3-b8c3-56d278eea07f
Class1 has Context: Id: 3abe0330-e94f-48a3-b8c3-56d278eea07f

In the sample above, when we write out the Class3, Class2, and Class1 objects to Debug.WriteLine, we find that each of these objects have a reference to the same DataContext. If we were to run this test again, the output might be:

Class3 has Context: Id: 109329ce-4058-4a35-9fd1-46d47c1e69e7
Class2 has Context: Id: 109329ce-4058-4a35-9fd1-46d47c1e69e7
Class1 has Context: Id: 109329ce-4058-4a35-9fd1-46d47c1e69e7

We see the exact same behavior, but it was a different object instance of DataContext for the new object graph.

This behavior also applies to objects passed in to the Container as an explicit argument:

        [Test]

        public void demonstrate_session_identity_with_explicit_argument()

        {

            DataContext context = new DataContext();

            Debug.WriteLine(“The context being passed in is “ + context);

 

            var class3 = container.With(context).GetInstance<Class3>();

            Debug.WriteLine(class3);

        }

The output of this unit test is:

The context being passed in is Id: 87ddccfd-a441-41fd-a86d-3f32987496ba
Class3 has Context: Id: 87ddccfd-a441-41fd-a86d-3f32987496ba
Class2 has Context: Id: 87ddccfd-a441-41fd-a86d-3f32987496ba
Class1 has Context: Id: 87ddccfd-a441-41fd-a86d-3f32987496ba

The point of the sample above is just to show that the object instance of DataContext passed into the Container is used to create the Class3, Class2, and Class1 objects.


Injecting Arrays of Services

StructureMap has always supported Dependency Injection of arrays of dependency objects.  New in StructureMap 2.5+ is a policy that if any array of dependencies is not explicitly specified, StructureMap will inject all possible instances of that dependency type.  The sample below illustrates this auto wiring policy.  I have a class called “ClassThatUsesValidators” that needs an array of IValidator objects.  Below, I’ve configured two different Instances of ClassThatUsesValidator, one that explicitly configures its children IValidator and another Instance that is just going to let auto wiring inject the IValidator’s.

    public interface IValidator

    {

    }

 

    public class Validator : IValidator

    {

        private readonly string _name;

 

        public Validator(string name)

        {

            _name = name;

        }

 

        public override string ToString()

        {

            return string.Format(“Name: {0}”, _name);

        }

    }

 

    public class ClassThatUsesValidators

    {

        private readonly IValidator[] _validators;

 

        public ClassThatUsesValidators(IValidator[] validators)

        {

            _validators = validators;

        }

 

        public void Write()

        {

            foreach (IValidator validator in _validators)

            {

                Debug.WriteLine(validator);

            }

        }

    }

 

    [TestFixture]

    public class ValidatorExamples

    {

        private Container container;

 

        [SetUp]

        public void SetUp()

        {

            container = new Container(x =>

            {

                x.ForRequestedType<IValidator>().AddInstances(o =>

                {

                    o.OfConcreteType<Validator>().WithCtorArg(“name”).EqualTo(“Red”).WithName(“Red”);

                    o.OfConcreteType<Validator>().WithCtorArg(“name”).EqualTo(“Blue”).WithName(“Blue”);

                    o.OfConcreteType<Validator>().WithCtorArg(“name”).EqualTo(“Purple”).WithName(“Purple”);

                    o.OfConcreteType<Validator>().WithCtorArg(“name”).EqualTo(“Green”).WithName(“Green”);

                });

 

                x.ForRequestedType<ClassThatUsesValidators>().AddInstances(o =>

                {

                    // Define an Instance of ClassThatUsesValidators that depends on AutoWiring

                    o.OfConcreteType<ClassThatUsesValidators>().WithName(“WithAutoWiring”);

 

                    // Define an Instance of ClassThatUsesValidators that overrides AutoWiring

                    o.OfConcreteType<ClassThatUsesValidators>().WithName(“ExplicitArray”)

                        .TheArrayOf<IValidator>().Contains(y =>

                        {

                            y.TheInstanceNamed(“Red”);

                            y.TheInstanceNamed(“Green”);

                        });

                });

            });

        }

 

        [Test]

        public void what_are_the_validators()

        {

            Debug.WriteLine(“With Auto Wiring”);

            container.GetInstance<ClassThatUsesValidators>(“WithAutoWiring”).Write();

            Debug.WriteLine(“=================================”);

            Debug.WriteLine(“With Explicit Configuration”);

            container.GetInstance<ClassThatUsesValidators>(“ExplicitArray”).Write();

        }

    }

The output of what_are_the_validators() is:

With Auto Wiring
Name: Red
Name: Blue
Name: Purple
Name: Green
=================================
With Explicit Configuration
Name: Red
Name: Green

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.
  • Just2play

    new to structure map. very insightfull. thanks.

  • http://holzerian.com Justin Holzer

    I agree that auto-wiring should be taken advantage of when possible. One exception I have to take with the examples given here and in many other places is that they focus on only the case where the developer has full control over the API. In reality, there are many times when the developer writes applications, such as plugins, where they have no control over the instantiation of the class.

    For instance, I am working on a plug-in module that is instantiated by the parent application. The plugin class must have a no-arg (default) constructor, and I have no way to tell the parent application to use StructureMap to create the instance of the plugin class. Therefore, if I want to use StructureMap in this case, I have no choice but to either call ObjectFactory directly, or create a facade/wrapper for calling it. I’d love to take adavantage of auto-wiring in this case, but I just see no way around using what has been deemed here as the “anti-pattern”.

  • David

    What if, in the first example, the implementation of IValidator accepts a parameter from the controller? My validator requires an instance of ModelState from the controller. I can’t seem to figure out how to inject a concrete Type for IValidator in this case.

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

    @jinksk,

    Can you be more specific? I don’t see anything wrong with that code.

  • jinksk

    The 2nd code section contains

    ObjectFactory.Initialize(x =>

    {

    // Set up the IValidator

    x.ForRequestedType().TheDefaultIsConcreteType();

    // Set up the IRepository

    x.ForRequestedType().TheDefault.Is.OfConcreteType()

    .WithCtorArg(“connectionString”).EqualToAppSetting(“CONNECTION-STRING”);

    });
    Maybe I’m missing something, but that code won’t work anywhere. Is the browser not displaying everything? Please repost that snippet.

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

    @Frans,

    That comes up fairly often. I think you’ll have to take that up with the CLR team. An IoC tool is arguably a hack around the static type system anyway.

  • http://weblogs.asp.net/fbouma Frans Bouma

    (I forgot: with DI initiated from the CTor, I mean that the Ctor calls out to the IoC container to inject whatever has to be injected, so it’s a little different from what you showed as an example, but still ties the receiver to the IoC container, which can be a concern, however at the same time, it solves the problem to always use a factory.

  • http://weblogs.asp.net/fbouma Frans Bouma

    While I agree that if possible, one should initiate DI from outside the object to create, it has one sad side-effect: you can’t use ‘new’.

    the problem with that is that if you make a mistake and accidently use ‘new’ instead of the factory, you don’t get the stuff injected, which could lead to hard-to-track down bugs.

    This alone could make some people to decide to go for DI from the Ctor, to make things more transparent for the developer who uses the classes which will receive injectables.

    I.o.w.: calling it an anti-pattern/FAIL etc. is much too strong, there are arguments for using a different approach.

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

    @Steve Py,

    It’s a valid concern, but there are diagnostics in SM that would let you scan a configuration all at one time and report missing dependencies. You wouldn’t get an NRE w/ SM. You’d get more specific SM exceptions earlier.

  • Steve Py

    The one irk I have with IoC is I can’t seem to shake the smell of Soft-Coding. The price of IoC is complexity, and while it gives you the power to configure your dependencies, in real-world projects that leads to a quagmire of configuration values. Situations always seem to arise where the auto-wiring just isn’t right for this situation and these require smelly work-arounds. Granted this is likely just a sign of a bad design, but I’m not the one that controls of the purse strings and delivery dates.

    One thing I do tend to add to any constructor / method that accepts references is a null check on the arguments to throw an ArgumentNullException with the parameter name. I bloody HATE NullReferenceExceptions. The argument exception with the parameter name often is enough to find/fix any configuration issues that manage to find their way into testing/production.

    The fact is that while IoC containers might look & smell like a tasty sticky-bun, you still need to check the raisins.

  • Paco

    An example in pseudo C#:

    class LogAttribute
    {

    private ILogger logger;
    public LogAttribute()
    {
    logger = IoC.Resolve();
    }

    public void OnControllerActionExecuting(FilterContext)
    {
    var message = complexStuffToCreateLogentry(context);
    logger.Log(message);
    }
    }

    I can already unit test it because an extra (non-default) constructor with the dependency in it.
    I don’t want to invoke the non-default constructor on the place where I use the attribute, because I have to inject the dependency on the calling class too and that will lead to constructors with lot’s of dependencies just to make the attribute usage possible.

    When this is unclear, I can mail or post the actual code tomorrow.

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

    @Paco,

    Can you paste some sample code? Or email it to me from the contact form?

    Jeremy

  • Paco

    I checked how many times I make a call to the container in the project I’m currently working on and I came to 12. 10 of those are done in attributes. Is there a way to cut that down?

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

    @Pete Johanson,

    One way to do it is to direct all requests like that to either a central EventAggregator / MessageBus and/or an ApplicationController. Then you can bury the service locator stuff there.

    You could inject the container itself into classes. That at least makes the dependency on the Container more transparent and helps with testability.

    In your case with the dialog box, I typically have the dialog form injected into the Presenter for later use anyway.

    And that gives me an idea for a STructureMap feature for later…

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

    @Daniel,

    Ok, I’m with you a bit more. Yes, absolutely you would inject a wrapper around the HttpContext, but there’s a bit more to it than that. You want as little coupling as possible between your code and the HttpContext. Ideally, you’d put a strongly typed wrapper around the HttpContext that’s expressed in terms of your application instead of dictionaries. More testability, cleaner code, less duplication of the dictionary access, and you can reuse the code outside of ASP.Net if that’s valuable.

    “So maybe to makes it clearer, do you think Singleton pattern to contain mostly Data oriented objects as a no-no and IoC should be used to provide the dependency resolution even from “within” a platform.”

    Yes, I do. It’s a small gain in many cases, but I’ve seen the ability to swap out something that used to be a Singleton become valuable later on. Besides, using an IoC frees you from hand rolling Singleton code.

  • http://blog@danielfernandes.net Daniel Fernandes

    @Jeremy :
    By Context object, what would you think if one always had to inject HttpContext to any code that needs it even though such class is core to a platform.
    I’m sure you understood that, maybe I am seeing a smell when maybe there isn’t :)
    So maybe to makes it clearer, do you think Singleton pattern to contain mostly Data oriented objects as a no-no and IoC should be used to provide the dependency resolution even from “within” a platform.

  • Pete Johanson

    Touching on the subject of “minimize the number of Service Locator (Container.Get*****) usages in your system”, I’ve been struggling in my head recently with the approach to do just that in a rich client scenario. (This happens to be cross-platform Gtk#, but it could just as easily apply to SWF, whatever).

    Let’s say in reaction to a certain user action (clicking a menu item), a certain amount of business logic happens, and then some dialog is supposed to appear.

    At some point, the business logic needs to say “Show Foo Dialog”. The naive approach would be to do ObjectFactory.GetInstance () and act on it… But what’s the alternative? The best I can think of is a IFooDialogFactory that would be injected, and calling factory.CreateDialog ().

    But then I’ve got a new factory for *every dialog I want to create*.

    What are others doing to solve this situation?

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

    @Daniel,

    I think the ASP.Net Provider model is an automatic FAIL for anything but the delivered providers.

    I actually like to use StructureMap as my configuration tool. It keeps your code decoupled from the configuration for better reuse, simpler code, and better testability.

    “On a different subject, what are your thoughts on Context objects that could definitely be injected by IoC but knowing you will need those throughout your layers (say a SecurityContext object) would you think this may be the wrong use case of a IoC?”

    Maybe I’m not thinking about this hard enough, but I don’t see any problem with that.

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

    Travis,

    I’ve got the “BuildUp()” functionality coming in 2.5.2 later this week to address the @#$$ed up ASP.Net architecture. Even then, why would it have to be any more than:

    _presenter = ObjectFactory.With(this).GetInstance();

    in the constructor of the WebForms page.

  • http://blog@danielfernandes.net Daniel Fernandes

    According to you, is it “IoC gone mad” to use the *Provider pattern to provide things as trivial as a configuration string ?
    I’ve done that in the past and I just ended up with a plethora of very simple classes doing little things, I’m all for SRP but it sometimes feels we’re decomposing things too much.

    On a different subject, what are your thoughts on Context objects that could definitely be injected by IoC but knowing you will need those throughout your layers (say a SecurityContext object) would you think this may be the wrong use case of a IoC?

    Cheers
    Daniel

  • http://www.heliosfx.com Travis

    “// FAIL!
    // This is the wrong way to use an IoC container. Do NOT invoke the container from
    // the constructor function. ”

    That is all peachy in a rose colored world, but sometimes we don’t have the *luxury* of instantiating control of our objects. cough Web Form Page cough, until we can inject into the Page class’s constructor, those of us living in the Web Forms world have to live with this “FAIL”.