StructureMap – Node Normalized Instances

This is the default style used for instances within Xml configuration.  This style is supported for backwards compatibility, but the Attribute Normalized style is strongly recommended for its terseness.

Next Prev

Instance Root Node

An Instance is defined in Xml starting from a root node.  The actual name of the root node varies depending upon the context that an Instance is being configured.  For example, the AddInstance, DefaultInstance, PluginFamily/Instance, Interceptor, and Source nodes in Xml configuration are all Instance roots.  The rules for an Instance node are the same regardless of the context.  The root node optionally specifies the name of the instance and the concrete type of the instance.

For a class called ColorRule,

[Pluggable("Color")]
public class ColorRule : Rule
{
private string _Color;
public string ID = Guid.NewGuid().ToString();
public ColorRule(string Color)
{
_Color = Color;
}
public string Color
{
get { return _Color; }
}
}

an Instance node might look like:

<Instance Key="Red" Type="Color">
<Property Name="Color" Value="Red" />
</Instance>

The “name” of an Instance is definied by the Key attribute.  The concrete type can be specified in one of two ways.  You can either use the “Type” attribute above to specify the aliased concrete type (if you’re using the [Pluggable] attribute in the code), or do it more explicitly by setting the PluggedType attribute to the assembly qualified name of the concrete type.

<Instance Key="Red" PluggedType="StructureMap.Testing.Widget.ColorRule, StructureMap.Testing.Widget">
<Property Name="Color" Value="Red" />
</Instance>

Primitive Properties (Strings and basic value types)

Primitive constructor or setter arguments are defined by adding a <Property Name=”propertyName” Value=”propertyValue”> node underneath the instance node.

[Pluggable("Color", "Only for testing")]
public class ColorWidget : IWidget
{
public ColorWidget(string Color)
{
_Color = Color;
}
}

 

<Widget Type="Color" Key="Red">
<Property Name="Color" Value="Red" />
</Widget>

Long Strings

There is an optional mode to define a property value inside a CDATA tag for very long strings like sql statements or Javascript templates.

<Property Name="bigProp">
<![CDATA[
select * from table
where
somecolumn = 'something' or
some_other_column = 'something else'
]]>
</Property>

Enumeration Properties

Enumeration arguments are defined the same way as primitive properties.  Use the string names of the enumeration for the values.

public enum BreedEnum
{
Hereford,
Angus,
Longhorn
}
[Pluggable("Cow")]
public class Cow
{
public BreedEnum Breed;
public long Weight;
public string Name;
public Cow(long Weight, BreedEnum Breed, string Name)
{
this.Breed = Breed;
this.Weight = Weight;
this.Name = Name;
}
}

 

<Instance Type="Cow" Key="Maggie">
<Property Name="Breed" Value="Angus" />
</Instance>

Dependency Properties

Child properties of non-primitive types are defined as embedded memento nodes.  Child properties can be either defined inline or use a reference to a named instance of the property type.  If a child property is omitted or defined with no value, StructureMap will use the default instance of the property type.

[PluginFamily, Pluggable("Default", "")]
public class GrandChild
{
public GrandChild(bool RightHanded, int BirthYear)
{
}
}
[Pluggable("Leftie", "")]
public class LeftieGrandChild : GrandChild
{
public LeftieGrandChild(int BirthYear) : base(false, BirthYear)
{
}
}
[PluginFamily, Pluggable("Default", "")]
public class Child
{
public Child(string Name, GrandChild MyGrandChild)
{
}
}

Inline Definition

<StructureMap.Testing.Widget.Child Type="Default" Key="Tom"> <Property Name="Name" Value="Tom" /> <Property Name="MyGrandChild" Type="Leftie"> <Property Name="BirthYear" Value="1984" /> </Property> </StructureMap.Testing.Widget.Child>

 

Reference Definition

 

<StructureMap.Testing.Widget.Child Type="Default" Key="Marsha"> <Property Name="Name" Value="Marsha"/> <Property Name="MyGrandChild" Key="Tommy"/> </StructureMap.Testing.Widget.Child>

Non Primitive Arrays

If a property or constructor argument is an array of a non-primitive type, create a child node to the top level instance with the form <Property Name=”propertyName”>.  Simply add new Instance nodes with the name <Property> under the property nodes for each element of the array.  These <Child> nodes are Attribute Normalized InstanceMemento’s and follow the same rules expressed in this document.

[Pluggable("Compound")] public class CompoundStrategy : IStrategy { public CompoundStrategy(IStrategy[] innerStrategies) { } }

 

<Instance Key="ArrayTest" Type="Compound"> <Property Name="innerStrategies"> <!-- Referenced Instance --> <Property Key="Red"></Property> <Property><!-- Default Instance --></Property> <!-- Inline Definition --> <Property Type="Random"> <Property Name="seed" Value="0.034"/> </Property> </Property> </Instance>

Primitive Arrays

Primitive arrays like string[] or int[] can be defined in Xml.  For a class with arguments like:

public ClassWithStringAndIntArray(int[] numbers, string[] strings) { _numbers = numbers; _strings = strings; }

The Xml configuration is:

 <DefaultInstance PluginType="StructureMap.Testing.Configuration.ClassWithStringAndIntArray, StructureMap.Testing" PluggedType="StructureMap.Testing.Configuration.ClassWithStringAndIntArray, StructureMap.Testing"> <Property Name="numbers" Values="1;2;3" Delimiter=";"/> <Property Name="strings" Values="1,2,3"/> </DefaultInstance>

By default, the Values attribute is assumed to be a comma delimited list.  The delimiter of the list can be optionally overriden by using the Delimiter attribute.

Dictionaries and NameValueCollection

Any form of IDictionary<Key, Value> or a NameValueCollection can be configured in Xml by the following syntax.  Say you have a class that needs a Dictionary of properties:

public class ClassWithDictionary
{
private readonly IDictionary<string, string> _dictionary;
public ClassWithDictionary(IDictionary<string, string> dictionary)
{
_dictionary = dictionary;
}
public IDictionary<string, string> Dictionary
{
get { return _dictionary; }
}
}

The “dictionary” argument to the constructor function could be defined as:

 <DefaultInstance
PluginType="StructureMap.Testing.Configuration.ClassWithDictionary, StructureMap.Testing"
PluggedType="StructureMap.Testing.Configuration.ClassWithDictionary, StructureMap.Testing">
<Property Name="dictionary">
<Pair Key='color' Value='red'/>
<Pair Key='state' Value='texas'/>
<Pair Key='direction' Value='north'/>
</Property>
</DefaultInstance>
Next Prev