Initializing and Configuring a StructureMap Container

More dribs and drabs of StructureMap documentation.  I’ve gotten quite a few questions over the difference between Initialize() and Configure().  I hope that this will help with that confusion.  Another goal is to present the Initialize() method.  StructureMapConfiguration has turned out to be a near disaster and is now deprecated in the trunk.  Initialize() was created as a (hopefully) less confusing alternative.  It definitely solves the problem of ordering calls.

 

The recommended mechanism for initializing the Container or ObjectFactory is the Initialize()
method.  The Initialize() method is new for StructureMap 2.5, and largely
driven by (my current love affair with Lambda’s) the confusion and misuse of
StructureMapConfiguration.  StructureMapConfiguration is still supported,
but it is deprecated in the code and will be eliminated in a future release.  Initialize() is a Nested Closure that
gives you a chance to express directives telling the Container how to construct
itself and add one or more sources of configuration. 

       
public Container(Action<ConfigurationExpression> action)

        {

           
var expression =
new
ConfigurationExpression();

           
action(expression);

 

           
construct(expression.BuildGraph());

        }

Typically, you would make a single call to the Initialize() method at
application start up (Global.asax for web application, or the main routine for a
desktop application).  The Container (ObjectFactory is simply a static
wrapper around a single Container) is completely initialized and configured by
the Initialize() method in one atomic action.  Any successive calls to
Initialize() will effectively wipe out any existing configuration and
effectively restart the Container.
  Here’s a sample usage of
Initialize():

           
ObjectFactory.Initialize(x =>

           
{

               
x.UseDefaultStructureMapConfigFile =

true;

 

               
x.AddRegistry(
new
CoreRegistry());

               
x.AddRegistry(
new
SearchRegistry());

               
x.AddRegistry(
new
WebCoreRegistry());

               
x.AddRegistry(
new
WebRegistry());

               
x.AddRegistry(
new
RuleRegistry());

           
});

Inside the Initialization() method you can declare directives against an
InitializationExpression object.  The InitializationExpression object has
these methods
for all all the possible configuration directives.

 

   
public
interface
IInitializationExpression

    {

       
// Directives on how to
treat the StructureMap.config file

       
bool UseDefaultStructureMapConfigFile {
set; }

       
bool IgnoreStructureMapConfig {
set; }

 

       
// Xml configuration from
the App.Config file

       
bool PullConfigurationFromAppConfig {
set; }

 

       
// Ancillary sources of Xml
configuration

       
void AddConfigurationFromXmlFile(string fileName);

       
void AddConfigurationFromNode(XmlNode node);

 

       
// Specifying Registry’s

       
void AddRegistry<T>()
where T :
Registry,
new();

       
void AddRegistry(Registry registry);

 

       
// Designate the Default
Profile.  This will be applied as soon as the

       
// Container is
initialized.

       
string DefaultProfileName {
get;
set; }

 

       
// … and the Registry DSL
as well

    }

 

 

Adding Configuration to an Existing Container

In contrast to Initialize(), the Configure() method allows you to add additional
configuration to an existing Container or ObjectFactory.  Think of this
scenario.  You’re building a composite application that contains multiple
modules spread over several assemblies, but you might not want to load any of
the configuration or types for a particular module until it’s requested by the
user.  In that case, you can use the Configure() method like this:

           
// This code would add any configuration from

           
// Registry classes found in the

           
// assembly named ‘MyApplication.Module1′

           
ObjectFactory.Configure(x =>

            {

               
x.Scan(scan =>

               
{

                   
scan.LookForRegistries();

                   
scan.Assembly(“MyApplication.Module1″);

               
});

            });

To summarize, Initialize() completely resets the configuration of a Container,
and Configure() is purely additive.  If Configure() should happen to be
called before Initialize(), it will set up the Container with the configuration
in the Configure() call.  Configure() offers a subset of the Initialize()
method (it leaves out the directives for the StructureMap.config file), and it
also includes the entire Registry DSL.  You can take advantage of that fact
to add a few types or instances at a time:

 

           
ObjectFactory.Configure(x =>

            {

               
x.ForRequestedType<ISomething>().TheDefaultIsConcreteType<SomethingOne>();

            });

 

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.