Home / StructureMap – Configuring StructureMap / StructureMap – Xml Configuration

StructureMap – Xml Configuration

While the Registry DSL is the strongly recommended means of configuring StructureMap, there will be times when reverting to Xml configuration is appropriate.  It’s certainly best for the type of configuration values that cannot be hard coded into compiled code (connection strings, file paths, Url’s, etc.).  StructureMap supports a wide range of Xml configuration capabilities due to its coming of age during the Xml-happy part of this decade.  At this point, the Xml configuration is mostly a supplement to the Registry DSL.  In this document you will find examples and explanations of the most common ways to use the Xml configuration.  A full reference to the older, but still supported, feature set is in the Xml Reference.

As shown in detail in Configuring StrutureMap, Xml configuration can be placed into any of the following sources:

  1. The App.config / Web.config file
  2. The StructureMap.config file in the same directory as your App.config file
  3. Any file you choose
  4. Any possible place that you could put Xml and retrieve it programmatically
Next Prev

<StructureMap> Element

Any Xml configuration starts with the <StructureMap> root node like this shown below:

<?xml version="1.0" encoding="utf-8" ?>
<StructureMap MementoStyle="Attribute" DefaultProfile="Connected">
</StructureMap>

The @DefaultInstance attribute is optional.  If it does exist, it’s the equivilant of calling ObjectFactory.Profile = “Connected” to change the Container or ObjectFactory to that Profile.  Setting the DefaultProfile attribute can be a great way to quickly change the way a system behaves.  I typically use the DefaultProfile as a way to switch a desktop application from fully connected to stubbed for testing or local usage.

Configuring Instances

The @MementoStyle attribute is very important.  This directs StructureMap how the Instances will be expressed in the Xml.  The two choices are:

  • “Node” — The older Node Normalized format.  This is the default format if the @MementoStyle attribute is missing (for backwards compatibility)
  • “Attribute” — The streamlined Attribute Normalized format introduced in the 1.0 release.  Attribute Normalized is highly recommended as it is much more terse.

Adding a Default Instance for a PluginType

The most common usage of Xml configuration is to specify the default Instance for a PluginType.  That is done with the <DefaultInstance> node like this one shown below:

<StructureMap MementoStyle="Attribute">
<DefaultInstance
PluginType="StructureMap.Testing.Widget.IWidget,StructureMap.Testing.Widget"
PluggedType="StructureMap.Testing.Widget.ColorWidget,StructureMap.Testing.Widget"
Scope="Singleton"
color="Red" />
</StructureMap>

In the sample node above, the parts are:

  1. PluginType — Assembly qualified name of the PluginType (the “T” in ObjectFactory.GetInstance<T>() )
  2. PluggedType — Assembly qualified name of the actual, concrete PluggedType
  3. Scope — Optionally defines the scope/lifecycle for this PluginType
  4. “color” — in this case, the ColorWidget class has a parameter in its constructor function named “color.”  Primitive constructor or setter arguments are just defined as attributes in the Xml node

Here’s a much more complicated example from my project.  The first Instance is related to NHibernate bootstrapping.  The second instance is another service related to sending emal:

<DefaultInstance
PluginType="DovetailCRM.Core.Persistence.ISessionSource,DovetailCRM.Core"
PluggedType="DovetailCRM.Core.Persistence.NHibernateSessionSource,DovetailCRM.Core"
Scope="Singleton">
<properties>
<Pair Key="connection.provider" Value="NHibernate.Connection.DriverConnectionProvider" />
<Pair Key="connection.driver_class" Value="NHibernate.Driver.SqlClientDriver" />
<Pair Key="dialect" Value="NHibernate.Dialect.MsSql2005Dialect" />
<Pair Key="hibernate.dialect" Value="NHibernate.Dialect.MsSql2005Dialect" />
<Pair Key="use_outer_join" Value="true" />
<Pair Key="connection.connection_string" Value="a connection string" />
<Pair Key="show_sql" Value="false" />
</properties>
</DefaultInstance>
<DefaultInstance
PluginType="DovetailCRM.Core.UserMessaging.IUserMessageDeliveryService, DovetailCRM.Core"
PluggedType="DovetailCRM.Core.UserMessaging.EmailUserMessageDeliveryService, DovetailCRM.Core"
Scope="Singleton"
hostAddress="127.0.0.1"
hostPort="2525"
defaultFromAddress="email address" />

Adding Additional Instances for a PluginType

Additional Instances for a PluginType can be added with the <AddInstance> node with several examples shown below.  The key attributes are the @PluginType (ISomething) and @PluggedType (Something : ISomething).  The <AddInstance> node represents an Instance.  See Node Normalized Instances and Attribute Normalized Instances for more information on configuring an Instance in Xml.

<StructureMap MementoStyle="Attribute">
<AddInstance
Key="Red"
PluginType="StructureMap.Testing.Widget.IWidget,StructureMap.Testing.Widget"
PluggedType="StructureMap.Testing.Widget.ColorWidget,StructureMap.Testing.Widget"
color="Red" />
<AddInstance
Key="Green"
PluginType="StructureMap.Testing.Widget.IWidget,StructureMap.Testing.Widget"
PluggedType="StructureMap.Testing.Widget.ColorWidget,StructureMap.Testing.Widget"
color="Green" />
<AddInstance 
PluginType="StructureMap.Testing.Widget.IWidget,StructureMap.Testing.Widget"
PluggedType="StructureMap.Testing.Widget.ColorWidget,StructureMap.Testing.Widget"
color="Purple" />
<AddInstance
Key="Blue"
PluginType="StructureMap.Testing.Widget.Rule,StructureMap.Testing.Widget"
PluggedType="StructureMap.Testing.Widget.ColorRule,StructureMap.Testing.Widget"
color="Blue"
Name="TheBlueOne"/>
</StructureMap>

Defining a Profile

A Profile can be defined with the Xml configuration.  The configuration for the Profile is strictly additive, meaning that any Xml configuration for a Profile will be combined with all other sources of configuration.  If there is conflicting configuration, the last configuration source processed will win.  Be cautious about splitting Profile definitions across multiple configuration sources.

To define a Profile in the Xml configuration, simply add a new <Profile> node and set the @Name attribute to the profile name.  After that, you need to include an <Override> node for each PluginType in the Profile.  Within the <Override> node, you can either reference a named Instance for that PluginType that is defined somewhere else, or configure a new Instance inline by nesting an <Instance> node within the <Override> node.  Examples of both techniques are shown below:

<?xml version="1.0" encoding="utf-8" ?>
<StructureMap MementoStyle="Attribute">
<Assembly Name="StructureMap.Testing.Widget"/>
<!--
If we already have Instances defined somewhere else, we can just specify
that the Profile will use the named Instance designated by the DefaultKey
attribute
-->
<Profile Name="Stubbed">
<!-- The <Override> node sets up the Profile specific override of a single PluginType -->
<Override Type="SomeAssembly.IService,SomeAssembly" DefaultKey="Stubbed"/>
</Profile>
<!-- Defining the Profile Instance inline with the <Instance> Node -->
<Profile Name="Blue">
<Override Type="StructureMap.Testing.Widget.IWidget,StructureMap.Testing.Widget">
<Instance Type="Color" color="Blue"/>
</Override>
<Override Type="StructureMap.Testing.Widget.Rule,StructureMap.Testing.Widget">
<Instance Type="Color" color="Blue"/>
</Override>
</Profile>
<!-- By the way, you can also make "Machine" specific overrides, but use with caution -->
<Machine Name="GREEN-BOX" Profile="Green"/>
<Machine Name="ORANGE-BOX">
<Override Type="StructureMap.Testing.Widget.IWidget,StructureMap.Testing.Widget">
<Instance Type="Color" color="Orange"/>
</Override>
</Machine>
</StructureMap>

Referencing Registries from Xml

StructureMap 2.5.3 adds the ability to include Registry configuration through Xml configuration.  This may be valuable in systems where you might be completely unable to do programmatic bootstrapping or modify the application startup to add bootstrapping.  Just add a <Registry> node to Xml configuration and put the assembly qualified name of the Registry class into the @Type attribute like this:

<?xml version="1.0" encoding="utf-8" ?> <StructureMap> <!-- Configure a Registry by just specifying the Assembly Qualified Name of a Registry Type --> <Registry Type="StructureMap.Testing.XmlFileRegistry, StructureMap.Testing"></Registry> </StructureMap>
Next Prev