I'm trying to figure out how to set up a different connection string upon each web request.
This is my scenario:
- one single webapp based on asp.net mvc 3 + ninject + entity framework
- one single entity model
- three phisically different databases with the same model
What I've tried to do so far is to set the default controller factory (passing the right connection string) by overriding the OnActionExecuting method of the base controller (every controller is inherited from a custom base) but if I try to access with two different users that should access different databases at the same time it doesn't work. It seems that the first user set his connection string and the second one pick the one it's already set without setting a new default controller.
Here's some code...
// Base controller
public class BaseController : Controller
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
var database = String.Empty;
switch (Request.Url.Host)
{
case "aaa.domain.local":
database = "AAA";
break;
case "bbb.domain.local":
database = "BBB";
break;
case "ccc.domain.local":
database = "CCC";
break;
}
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory(WebConfigurationManager.ConnectionStrings[database].ConnectionString));
}
}
// Ninject controller factory
public class NinjectControllerFactory : DefaultControllerFactory
{
private IKernel _kernel;
public NinjectControllerFactory()
{
}
public NinjectControllerFactory(string connectionString)
{
_kernel = new StandardKernel(new ABCServices(connectionString));
}
protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
return null;
return (IController)_kernel.Get(controllerType);
}
private class ABCServices : NinjectModule
{
private string _connectionString;
public ABCServices(string connectionString)
{
_connectionString = connectionString;
}
public override void Load()
{
Bind<IUsersRepository>().
To<SqlUsersRepository>().
InRequestScope().
WithConstructorArgument("connectionString", _connectionString);
}
}
}
As you can see I'm using .InRequestScope() to limit the ninject implementation to the single request. Am I right or not?