Base solution for your next web application
Open Closed

Migrator seperate appsettings.json #5782


User avatar
0
kpmg created

Hi Everyone.

I am dealing with various environments and I want to adjust the migrator project to be able to deal with more than one default connection string.

My idea was to use command line arguments f.e. -e environmentName that the appsettings.environmentName.json gets loaded. Unfortunately, I can’t pass that argument to the bootstrapper during startup.

Program.cs

var bootstrapper = AbpBootstrapper.Create<TestMigratorModule>()

So my idea was to reinitialize it with the environment name

using (var test = bootstrapper.IocManager.ResolveAsDisposable<TestMigratorModule>())
{
     test.Object.ReInitialize(_environment);
}

So far so good. In my IConfigurationRoot the builder created two configurations. But, in the MultiTenantMigrateExecuter.cs in the Run method there is no way to reference the second configuration.

var hostConnStr = _connectionStringResolver.GetNameOrConnectionString(new ConnectionStringResolveArgs(MultiTenancySides.Host));
if (hostConnStr.IsNullOrWhiteSpace())
{
Log.Write("Configuration file should contain a connection string named 'Default'");
                return;
}

My goal is: Basicly I want to copy paste alle appsettings.XYZ.json from the .Web.Host project to the migrator and use the connection string of one of these config files. Another option would be to just add all connection strings with a different name in the appsettings.json of the migrator project. How can I get this done?

Kinde regards! Christian


2 Answer(s)
  • User Avatar
    0
    kpmg created

    I found an OK-solution for that.

    I added all connection strings in the appsettings.json of the migrator project and adjusted the Main() function a little bit. So the user can choose between the different connection strings. it makes it much easier to update or create different environments.

    Here is the code after the bootstrapper.Initialize();

    using (var test = bootstrapper.IocManager.ResolveAsDisposable<TestMigratorModule>())
                    using (var log = bootstrapper.IocManager.ResolveAsDisposable<Log>())
                    {
                        var databases = test.Object.GetEnviroments();
    
                        string command = String.Empty;
                        while (!command.IsIn("E", "e"))
                        {
                            int i = 0;
                            Console.WriteLine("ID\t\tConnection Key");
                            foreach (var kv in databases)
                            {
                                Console.WriteLine(i + "\t\t" + kv.Key);
                                i++;
                            }
    
                            log.Object.Write("Type in the ID of the database you want to connect to OR e for Exit: ");
                            command = Console.ReadLine();
                            int result = -1;
    
                            if (int.TryParse(command, out result))
                            {
                                if (result >= databases.Count || result < 0)
                                {
                                    log.Object.Write("The ID you entered does not exist. Try again.");
                                }
                                else
                                {
                                    test.Object.SetEnvironment(databases[result].Key);
    
                                    using (var migrateExecuter = bootstrapper.IocManager.ResolveAsDisposable<MultiTenantMigrateExecuter>())
                                    {
                                        migrateExecuter.Object.Run(_skipConnVerification);
                                        log.Object.Write("Migration of "+ databases[result].Key+ " ended.");
                                    }
                                }
                            }
                        }
                    }
    

    And then the new functions in the TestMigratorModule.cs look like this:

    public List<KeyValuePair<string, string>> GetEnviroments()
            {
                string connectionStringSection = "ConnectionStrings";
                List<KeyValuePair<string, string>> ret = new List<KeyValuePair<string, string>>();
                foreach (var kv in _appConfiguration.GetSection(connectionStringSection).AsEnumerable())
                {
                    string cleanKey = string.Empty;
                    if (!string.IsNullOrEmpty(kv.Value))
                    {
                        cleanKey = kv.Key.Substring(connectionStringSection.Length + 1);
                        ret.Add(new KeyValuePair<string, string>(cleanKey, kv.Value));
                    }
                }
                return ret;
            }
    
            public void SetEnvironment(string environment)
            {
                Configuration.DefaultNameOrConnectionString = _appConfiguration.GetConnectionString(
                    environment
                    );
            }
    

    Perhaps this helps someone.

  • User Avatar
    0
    murat.yuceer created

    Just add this lines XXXMigratorModule.cs

        public XXXMigratorModule(KuysEntityFrameworkCoreModule abpZeroTemplateEntityFrameworkCoreModule)
        {
            abpZeroTemplateEntityFrameworkCoreModule.SkipDbSeed = true;
            
            _appConfiguration = AppConfigurations.Get(
                typeof(KuysMigratorModule).GetAssembly().GetDirectoryPathOrNull(),
                Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")
            );
        }