SourceForge.net Logo

Home
StructureMap on SourceForge
Basic Architecture
Concepts
API Documentation
FAQ
Configuration Schema
    Memento Sources
    Node Normalized Xml
    Attribute Normalized Xml
    Attribute Usage
    Instance Lifecyle Scoping
Configuration Management
    StructureMapDoctor
    StructureMapExplorer
    deployment Task
    verification Task
    ValidationMethod Attribute
    Other NAnt Tasks
Troubleshooting
Singleton Injection

Basic Architecture

Domain Model

 

Workflow

Step 1.)  Build a PluginGraph

At runtime, the first utilization of StructureMap triggers an initialization of the internal structures for building classes.  The first step is to find a PluginGraph of all of the interfaces and classes that should be built by StructureMap, and the relationships between concrete and abstract CLR Types.  For example, StructureMap may be directed to built types of an interface called "IGateway."  The concrete classes to plug into "IGateway" could be "RemoteGateway", "StubbedGateway", and "LocalGateway" (aliased in StructureMap as "Remote", "Stubbed", and "Local" respectively). 

The construction of the PluginGraph is done by a helper class called PluginGraphBuilder.  PluginGraphBuilder first reads the StructureMap.config file in the executing directory of the AppDomain.  PluginGraphBuilder searches through the xml in config file looking for assembly references, explicitly defined PluginFamily's, and defined Plugin's.  Finally the PluginGraph is "sealed."  When the PluginGraph is sealed it examines every exported CLR Type in the assemblies referenced for types marked with StructureMap attributes to add implicitly defined PluginFamily's and Plugin's.  Any class marked as Pluggable will be made a Plugin to any PluginFamily where it could fit.

Step 2.)  Construct the InstanceManager Hierarchy

Once the PluginGraph is created, an InstanceManager hierarchy of objects is created to perform the actual instantiation of the targeted objects.  The InstanceManager takes in the PluginGraph and creates a new InstanceFactory object for each PluginFamily CLR Type.  The InstanceFactory has an optionally defined MementoSource member that is the source for configuration information for that particular MementoSource.  By default, an InstanceFactory will get a MementoSource that retrieves XML nodes from the StructureMap.config file.  On instantiation, an InstanceFactory will create a collection of InstanceBuilder objects for each concrete CLR Type that plugs into the InstanceManager.PluginType member.  The InstanceBuilder classes are emitted into a new in-memory dynamic assembly.

Step 3.)  Set the Default Instance Keys

The last step of instantiation is to determine the default configured instance for each InstanceFactory/PluginFamily.  In order of precedence, the default instance key is determined by:

  1. The overrides for a set profile, either at runtime or in the StructureMap.config file
  2. Machine-level overrides set in the StructureMap.config file
  3. Explicitly definined defaults set in the individual <PluginFamily> elements in the StructureMap.config file
  4. An optional "DefaultKey" property on a [StructureMap.PluginFamily] attribute

The default keys can be set or reset at runtime through ObjectFactory.

Step 4.)  Retrieve an Instance

Whether creating the default instance or a named instance, the sequence is very similar.  A caller requests a certain Type of object from the ObjectFactory.GetInstance() or ObjectFactory.GetNamedInstance() methods.  ObjectFactory delegates to its static InstanceManager member.  InstanceManager selects the proper InstanceFactory object based on the requested Type.  InstanceFactory uses either the default instance key or the named instance key to find the matching InstanceMemento from its MementoSource.  Once InstanceFactory has the InstanceMemento, it determines the correct InstanceBuilder by the ConcreteKey property of the InstanceMemento.  Finally, the selected InstanceBuilder object takes the InstanceMemento object, reads the proper properties, and creates the requested object and returns through the calling chain.

 

Domain Classes

PluginFamily

Conceptually speaking, a PluginFamily object represents a point of abstraction or variability in the system.  A PluginFamily defines a CLR Type that StructureMap can build, and all of the possible Plugin’s implementing the CLR Type.

Plugin

Represents a concrete class that can be built by StructureMap as an instance of the parent PluginFamily’s PluginType. The properties of a Plugin are the CLR Type of the concrete class, and the human-friendly concrete key that StructureMap will use to identify the Type.

PluginGraph

A PluginGraph models the entire listing of all PluginFamily’s and Plugin’s controlled by StructureMap within the current AppDomain. The scope of the PluginGraph is controlled by a combination of custom attributes and the StructureMap.config class

InstanceMemento

A GoF Memento pattern class that represents a configuration of an object instance that is available from StructureMap. An InstanceMemento can be thought of as a dehydrated object

MementoSource

A mechanism for retrieving a named InstanceMemento. MementoSource is an interface that can be plugged into StructureMap. An example of a MementoSource is the XmlFileMementoSource class that retrieves InstanceMemento objects from an Xml file. Users can create alternative MementoSource’s for usage with StructureMap.

InstanceBuilder

An emitted class that can assemble and create an object instance from an InstanceMemento. There is always one InstanceBuilder created for each Plugin.

InstanceFactory

Creates named and default object instances of a CLR type defined by the PluginType property. An InstanceFactory object uses a MementoSource to find InstanceMemento objects, and a collection of InstanceBuilder classes to build each unique concrete type.

InstanceManager

A collection of InstanceFactory classes. Creates object instances of multiple types. Helps individual InstanceBuilder classes create children instances

ObjectFactory

The Façade class for easy access to StructureMap functionality. Provides a static wrapper to manage object lifetime of an InstanceManager class for the current AppDomain.  All normal usage of StructureMap is through this class.  It is, however, possible to reuse the other classes for custom plugin scenarios.