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

"structuremap.deployment" NAnt Task

The structuremap.deployment NAnt task is a utility to deploy a subset copy of a StructureMap.config file based on filter rules.  It is often valuable or even necessary to have multiple configurations for an application.  During the pilot project for StructureMap the team had different configurations for developer workstations, smoke tests, the build server, and and several testing environments.  Roughly double the configurations for client versus server deployments.  The cost of maintaining several similar configuration files became too daunting and led to duplicated effort.  Anytime a change or addition was made to the configuration, up to eight or nine configuration files had to be modified in a similar manner.

To eliminate some of this overhead and make the deployment be more reliable, the team created a facility to keep all configuration options in a master configuration file.  The deployment NAnt task was added to the build script to create the individual configuration files as a part of the continuous integration process.  Combined with the validation task, this eased the overhead of maintaining and expanding the configuration for the system.

Usage

The following conditions must be met for the deployment task to function.  Some of these limitations may be eliminated in a later version.

  1. The StructureMap.dll and StructureMap.DeploymentTasks.dll must both be in the target path for the NAnt executable
  2. The StructureMap.dll must be in the same directory as the configuration file specified by the configPath argument
  3. All application assemblies must be in the same directory as the configuration file specified by the configPath argument
Arguments
Argument Description
configPath The path to the source configuration file
destinationPath The path to the new derived configuration file
deploymentTarget Optional argument specifying the deployment target.  The intention of this argument was to filter out assemblies and plugin types by physical deployment.  For example, setting a deploymentTarget="Client" will filter out any plugin or plugged types and the resultant instances from any assembly that is not deployed to the "Client" target. 
profile Optional argument specifying the active profile from the source configuration file.  If this argument is specified, the destination configuration file will be filtered by the default instances specified by the <Profile> element in the source configuration file.  For each plugin type configured in the specified <Profile> element, the default instance will be set to the instance from the profile, and all other instances will be discarded.  For example, setting profile="Test" will use the instance defaults from the "Test" profile and discard any instances from the "Development" and "Production" profiles.  All <Profile> elements will also be discarded in the deployment.
machineOption

Optional argument used to control the handling of the <Machine> elements.  The possible values are:

  1. "IgnoreMachineOverrides" - The <Machine> elements are ignored and discarded
  2. "CopyMachineOverrides" - Default value.  The <Machine> elements are copied into the destination file
  3. "UseCurrentMachineOverride" - The instance defaults of the <Machine> element matching the computer name running the NAnt task will be applied as a filter to the instances in the destination file in exactly the same manner as setting the "profile" argument.  The "profile" argument has precedence over the machineOption="UseCurrentMachineOverride" argument.
Sample NAnt Configuration
	
<target name="testDeploymentTask">
	<property name="deployment.dir" value="source\StructureMap.Testing.DeploymentTasks\bin\release\"/>
	<property name="source.config" value="${deployment.dir}DeploymentSourceConfig.xml"/>
	
	<structuremap.deployment configPath="${source.config}"
		destinationPath="${deployment.dir}WithProfileAndNothingElseCopyMachineOverrides.xml.actual"
		profile="Blue"
		machineOption="CopyMachineOverrides"/>

	<structuremap.deployment configPath="${source.config}"
		destinationPath="${deployment.dir}WithProfileAndNothingElseIgnoreMachineOverrides.xml.actual"
		profile="Blue"
		machineOption="IgnoreMachineOverrides"/>
		
	<structuremap.deployment configPath="${source.config}"
		destinationPath="${deployment.dir}DeploymentTargetIsClientCopyMachineOverrides.xml.actual"
		deploymentTarget = "Client"
		machineOption="CopyMachineOverrides"/>
</target>					
					
Source File
<StructureMap>
	<Assembly Name="MyApp.Data" Deploy="Server"/>
	<Assembly Name="MyApp.Common" Deploy="All" />
	<Assembly Name="MyApp.Stub" Deploy="Test" />
	
	<Profile Name="Dev">
		<Override Type="MyApp.Common.IDirectory" DefaultKey="UnitTest"/>
	</Profile>
	
	<Profile Name="Build">
		<Override Type="MyApp.Common.IDirectory" DefaultKey="Test"/>
		<Override Type="MyApp.Common.IDatabase" DefaultKey="Build"/>
	</Profile>
	
	<Profile Name="Test">
		<Override Type="MyApp.Common.IDirectory" DefaultKey="Test"/>
		<Override Type="MyApp.Common.IDatabase" DefaultKey="Test"/>
	</Profile>
	
	<Profile Name="Production">
		<Override Type="MyApp.Common.IDirectory" DefaultKey="Production"/>
		<Override Type="MyApp.Common.IDatabase" DefaultKey="Production"/>
	</Profile>
	
	<Machine Name="DEV-1" Profile="Dev">
		<Override Type="MyApp.Common.IDatabase" DefaultKey="Dev1"/>
	</Machine>
	<Machine Name="DEV-2" Profile="Dev">
		<Override Type="MyApp.Common.IDatabase" DefaultKey="Dev2"/>
	</Machine>
	<Machine Name="DEV-3" Profile="Dev">
		<Override Type="MyApp.Common.IDatabase" DefaultKey="Dev3"/>
	</Machine>
	

	<PluginFamily Assembly="MyApp.Common" Type="MyApp.Common.IDatabase" DefaultKey="Build">
		<Plugin Assembly="MyApp.Stub" Type="MyApp.Stub.StubDatabase" ConcreteKey="Stub"/>
		<Plugin Assembly="MyApp.Data" Type="MyApp.Data.MSSQLDatabase" ConcreteKey="MSSQL"/>
		
		
		<Instance Type="Stub" Key="UnitTest"/>
		<Instance Type="MSSQL" Key="Dev1">
			<Property Name="connectionString" Value="data source=devserver;initial catalog=dev1"/>
		</Instance>
		<Instance Type="MSSQL" Key="Dev2">
			<Property Name="connectionString" Value="data source=devserver;initial catalog=dev1"/>
		</Instance>
		<Instance Type="MSSQL" Key="Dev3">
			<Property Name="connectionString" Value="data source=devserver;initial catalog=dev1"/>
		</Instance>
		<Instance Type="MSSQL" Key="Build">
			<Property Name="connectionString" Value="data source=devserver;initial catalog=build"/>
		</Instance>
		<Instance Type="MSSQL" Key="Test">
			<Property Name="connectionString" Value="data source=testserver;initial catalog=test"/>
		</Instance>
		<Instance Type="MSSQL" Key="Production">
			<Property Name="connectionString" Value="data source=prodserver;initial catalog=MyApp"/>
		</Instance>
	</PluginFamily>
	
	<PluginFamily Assembly="MyApp.Common" Type="MyApp.Common.IDirectory" DefaultKey="Build">
		<Plugin Assembly="MyApp.Stub" Type="MyApp.Stub.StubDirectory" ConcreteKey="Stub"/>
		<Plugin Assembly="MyApp.Data" Type="MyApp.Data.ActiveDirectory" ConcreteKey="ActiveDirectory"/>
	
	
		<Instance Type="Stub" Key="UnitTest">
			<Property Name="filePath" Value="\\devserver\development\testusers.xml" />
		</Instance>
		<Instance Type="ActiveDirectory" Key="Test">
			<Property Name="Domain" Value="TestDomain"/>
		</Instance>
		<Instance Type="ActiveDirectory" Key="Production">
			<Property Name="Domain" Value="ProductionDomain"/>
		</Instance>
	</PluginFamily>

</StructureMap>
		
Filter by Profile
<structuremap.deployment configPath="${source.config}"
	destinationPath="${deployment.config}"
	profile="Test"
	machineOption="IgnoreMachineOverrides"/>
		
Destination File
<StructureMap>
	<Assembly Name="MyApp.Data" Deploy="Server"/>
	<Assembly Name="MyApp.Common" Deploy="All" />
	<Assembly Name="MyApp.Stub" Deploy="Test" />

	<PluginFamily Assembly="MyApp.Common" Type="MyApp.Common.IDatabase" DefaultKey="Test">
		<Plugin Assembly="MyApp.Stub" Type="MyApp.Stub.StubDatabase" ConcreteKey="Stub"/>
		<Plugin Assembly="MyApp.Data" Type="MyApp.Data.MSSQLDatabase" ConcreteKey="MSSQL"/>

		<Instance Type="MSSQL" Key="Test">
			<Property Name="connectionString" Value="data source=testserver;initial catalog=test"/>
		</Instance>
	</PluginFamily>
	
	<PluginFamily Assembly="MyApp.Common" Type="MyApp.Common.IDirectory" DefaultKey="Test">
		<Plugin Assembly="MyApp.Stub" Type="MyApp.Stub.StubDirectory" ConcreteKey="Stub"/>
		<Plugin Assembly="MyApp.Data" Type="MyApp.Data.ActiveDirectory" ConcreteKey="ActiveDirectory"/>

		<Instance Type="ActiveDirectory" Key="Test">
			<Property Name="Domain" Value="TestDomain"/>
		</Instance>
	</PluginFamily>
</StructureMap>