Configuring StructureMap using web.config
For the project I am currently working on I chose StructureMap as the dependency injection framework. The configuration for StructureMap is pretty easy – in my case it looked something like this.
public static void ConfigureStructureMap()
{
ObjectFactory.Initialize(x =>
{
x.ForRequestedType<IAuthenticationService>().TheDefaultIsConcreteType<AuthenticationService>();
x.ForRequestedType<ILdapAuthenticationService>().TheDefaultIsConcreteType<LdapAuthenticationService>();
x.ForRequestedType<ICrmService>().TheDefaultIsConcreteType<CrmService>();
x.ForRequestedType<IOneTimePinService>().TheDefaultIsConcreteType<OneTimePinService>();
x.ForRequestedType<IUserRepository>().TheDefaultIsConcreteType<UserRepository>();
x.ForRequestedType<IThreadFactory>().TheDefaultIsConcreteType<ThreadFactory>();
});
}
Pretty cool – you just specify all the the interfaces and the corresponding concrete types. StructureMap also allows you to do loads of extra configuration options, but in my case this is what I will be using 99% of the time.
Move the configuration to the web.config
Because some of the services invoke webservices which are unavailable to me during development I swapped some of the concrete implementations for mock services. Because I didn’t really want to change the code to allow this change I decided to move the configuration into the web.config file. I found the StructureMap documentation a little confusing at some point – I simply couldn’t find a proper example of how to configure a few simple classes as the default concrete types. So hopefully this post will serve as an example.
Firstly, add the following tag inside the
<section name="StructureMap" type="StructureMap.Configuration.StructureMapConfigurationSection,StructureMap"/>
Now you need to tell StructureMap to read all the settings from the config file.
public static void ConfigureStructureMap()
{
ObjectFactory.Initialize(x =>
{
x.PullConfigurationFromAppConfig = true;
});
}
And now you can add all your StructureMap settings – you can do this anywhere inside the
<StructureMap>
<Assembly Name="ProjectName.Server" />
<PluginFamily Type="ProjectName.Server.Services.IAuthenticationService" Assembly="ProjectName.Server" DefaultKey="Default">
<Plugin Type="ProjectName.Server.Services.Mocks.MockAuthenticationService" Assembly="ProjectName.Server" ConcreteKey="Default" />
<!--Plugin Type="ProjectName.Server.Services.AuthenticationService" Assembly="ProjectName.Server" ConcreteKey="Default" /-->
</PluginFamily>
<PluginFamily Type="ProjectName.Server.Services.ILdapAuthenticationService" Assembly="ProjectName.Server" DefaultKey="Default">
<Plugin Type="ProjectName.Server.Services.LdapAuthenticationService" Assembly="ProjectName.Server" ConcreteKey="Default" />
</PluginFamily>
<PluginFamily Type="ProjectName.Server.Services.ICrmService" Assembly="ProjectName.Server" DefaultKey="Default">
<Plugin Type="ProjectName.Server.Services.CrmService" Assembly="ProjectName.Server" ConcreteKey="Default" />
</PluginFamily>
<PluginFamily Type="ProjectName.Server.Services.IOneTimePinService" Assembly="ProjectName.Server" DefaultKey="Default">
<Plugin Type="ProjectName.Server.Services.OneTimePinService" Assembly="ProjectName.Server" ConcreteKey="Default" />
</PluginFamily>
<PluginFamily Type="ProjectName.Server.Data.Repositories.IUserRepository" Assembly="ProjectName.Server" DefaultKey="Default">
<Plugin Type="ProjectName.Server.Data.Repositories.UserRepository" Assembly="ProjectName.Server" ConcreteKey="Default" />
</PluginFamily>
<PluginFamily Type="ProjectName.Server.Tools.IThreadFactory" Assembly="ProjectName.Server" DefaultKey="Default">
<Plugin Type="ProjectName.Server.Tools.ThreadFactory" Assembly="ProjectName.Server" ConcreteKey="Default" />
</PluginFamily>
</StructureMap>
Hopefully this will save someone some time. Happy coding.