I am trying to figure out how to use IoC in situations where the dependent classes can change based on some variable in the application (in this case, Session state). For e
How the Repository instance is created, as well as its lifetime, is of no concern of the Controller.
When you register components in the container, you should specify the lifetime of the component. Depending on your implementation, you may simply choose to set the lifefime of the Repository to follow the session.
In any case you could use a factory to create the repository from the session, but do this from outside the Controller.
You definitely need to get rid of the default constructor.
Off the top of my head I can't remember how to do this in Unity or StructureMap, so here's a Castle Windsor example.
Define an Abstract Factory:
public interface IRepositoryFactory
{
Repository Create();
}
and an implementation
public class MyRepositoryFactory : IRepositoryFactory
{
private readonly HttpContextBase httpContext;
public MyRepositoryFactory(HttpContextBase httpContext)
{
if (httpContext == null)
{
throw new ArgumentNullException("httpContext");
}
this.httpContext = httpContext;
}
#region IRepositoryFactory Members
public Repository Create()
{
// return Repository created from this.httpContext
}
#endregion
}
Now register all the stuff
container.AddFacility<FactorySupportFacility>();
container.Register(Component.For<IRepositoryFactory>()
.ImplementedBy<MyRepositoryFactory>()
.LifeStyle.PerWebRequest);
container.Register(Component.For<Repository>()
.UsingFactory((IRepositoryFactory f) => f.Create())
.LifeStyle.PerWebRequest);
Here I've used the PerWebRequest lifestyle, but if you want to optimize you might want to create a custom PerWebSession lifestyle. This is not too hard to do in Castle, but I can't remember how hard it is in other DI Containers.
You will also need to register HttpContextBase, since MyRepositoryFactory depends on it.