What is Contextual Binding?
Contextual Binding is the ability to switch out different concrete implementations of a service (i.e. class) at runtime depending on the context in which they are used.
One really cool thing about StructureMap is that it is very flexible. Most times there are multiple ways to accomplish the same goal. The reason for this is because everyone's needs are different and the tool takes this into account.
There are 2 (at least 2, maybe more :) ) ways that we can perform contextual binding with StructureMap.
Context Setup - The classes we will be using
We will be creating a 'consumer' who likes to consumer soda. The type of soda that the consumer will drink will be injected at runtime via StructureMap and we will swap the soda out at runtime with contextual binding
Consumer Class - The class that consumes Soda
public class Consumer
{
public Consumer(ISoda soda)
{
Soda = soda;
}
public string WhatTypeOfSodaAreYouDrinking()
{
return Soda.Name;
}
public Int32 HowManyCaloriesDoYouHave()
{
return Soda.Calories;
}
public ISoda Soda { get; set; }
}
ISoda Interface - The contract for our soda objects
public interface ISoda
{
string Name { get;}
Int32 Calories { get; }
}
DrPepper Class - An implementation of ISoda
public class DrPepper : ISoda {
public string Name { get { return "DrPepper"; } }
public int Calories { get { return 250; } }
}
DietCoke Class - An implementation of ISoda
public class DietCoke : ISoda
{
public string Name { get { return "Diet Coke"; } }
public Int32 Calories { get { return 99; } }
}
Setting up StructureMap to know about the various classes
StructureMapConfiguration.ForRequestedType<consumer>().AddConcreteType<consumer>();
StructureMapConfiguration.AddInstanceOf<ISoda>().UsingConcreteType<DrPepper>().WithName( "DrPepper" );
StructureMapConfiguration.AddInstanceOf<ISoda>().UsingConcreteType<DietCoke>().WithName("DietCoke");
Setting the Default Instance on the fly:
If you only need/want to swap out a single class at runtime the simplest way may be to just change the instance on the fly.
The code below will show how to do that.
ObjectFactory.SetDefaultInstanceName<ISoda>( "DietCoke" );
var consumer = ObjectFactory.GetInstance<Consumer>();
// we now should have a consumer with an instance of DietCoke
Using Profiles:
A profile in StructureMap is basically a configuration group that allows you to prewire which types you would like to use for various contracts ahead of time. By using a contract you can swap out many concrete types with a single line of code.
The code below will show how to setup a profile as well as how to use that profile.
Creating the profiles
ProfileExpression drPepperProfile = StructureMapConfiguration.CreateProfile( "DrPepper" );
drPepperProfile.For<ISoda>().UseConcreteType<DrPepper>();
ProfileExpression dietCokeProfile = StructureMapConfiguration.CreateProfile("DietCoke");
dietCokeProfile.For<ISoda>().UseConcreteType<DietCoke>();
Setting the profiles
ObjectFactory.Profile = "DrPepper";
var consumer = ObjectFactory.GetInstance<Consumer>();
// we now should have a consumer with an instance of DrPepper
As you can see, setting up Contextual Binding in StructureMap is pretty easy and is a very powerful tool.
Till next time,
[----- Remember to check out DimeCasts.Net -----]
Posted
08-13-2008 7:13 AM
by
Derik Whittaker