Search code examples
bindingninjectconnection-stringcurrentculture

Switch connection string based upon culture when using NInject


Please can anyone advise if it is possible to switch connection strings for a DbContext using Ninject binding, based upon Current Culture? My current (non-working) cod is as below.

    private static IKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        try
        {
            kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
            kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

            RegisterServices(kernel);
            return kernel;
        }
        catch
        {
            kernel.Dispose();
            throw;
        }
    }

    private static string GetCultureBasedConnectionString()
    {
        string culture = "de-DE"; // TODO Replce with Thread.CurrentThread.CurrentCulture.Name
        string cultureBasedConnectionString = ConnectionStringHelper.GetConnectionStringWithCulture(culture);
        return cultureBasedConnectionString;
    }

    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<ApplicationDb>().To<ApplicationDb>()
            .InRequestScope()
            .WithConstructorArgument("connectionString", context => GetCultureBasedConnectionString());
        .
        .
        .
    }

This is based upon the example here, Ninject - dynamically specifying a connection string based on a sub domain, but it does not call through to my GetCultureBasedConnectionString() method on each request except when the application starts up...

I have read here on So that using NInjects Rebind() method is not good.

This SO thread also did not get me in the right direction, either.


Solution

  • Yes you are describing the expected behavior. The binding code is executed when.. well when you call Bind - and not every time the type is retrieved. The Func/Method specified in ToMethod would be executed every time the binding is applied.

    Although i believe you can simplify your code to:

    kernel.Bind<ApplicationDb>().To<ApplicationDb>()
            .InRequestScope()
            .WithConstructorArgument(
                "connectionStringGetter",
                context => GetCultureBasedConnectionString());
    

    and thus get rid of ConnectionStringGetter().