Skip to main content

Software Development

Config-Per-Site in Optimizely Multi-Tenant Environments

Abstract colorful grid surrounded by glowing particles

Recently, I was given a task at work where we needed a multisite configuration. We all know that multi-environment is as easy as appsettings.<environment_name>.config. What about in multi-tenant environments? You can’t have appsettings.site1.config and appsettings.site2.config on your site! Well, not without a little extra work…

Let me introduce AddKeyPerFile; this handy little function you set up in your Program.cs will enumerate the files in a directory and add them to your Configuration.

“Alright!” you must be thinking, “Show me how this miracle function works…” Well, let’s get to it! First, you’ll want to identify the config sections unique to each site and put them in their own folder. I do this by site name because it makes the most sense by our conventions; if something else works for your practice, these names aren’t set in stone.

Now, to suck those values into your config, there’s a straight line to add to the Program.cs:

 var configBuilder = new ConfigurationBuilder()
 .AddJsonFile("appsettings.json", false, true)
 .AddJsonFile($"appsettings.Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", true, true)
 .AddJsonFile("appsettings.local.json", true, true)
 .AddJsonFile($"appsettings.{Environment.MachineName}.json", true, true)
 .AddKeyPerFile(Path.Combine(Directory.GetCurrentDirectory(), "SiteConfigs"), true, true)

AddKeyPerFile expects at least a fully qualified path to the config folder, no short-cutting this. The following two books indicate if the file is optional and to reload the file if it changes, respectively, and these are optional.

So, now that we’ve got them in the Configuration, how do we get them out? Simple:


This is where your file naming convention comes into play; you need to be able to look them up by name in Configuration, so make sure it’s something you can work with. However, there’s a snag with this… We get the entire contents of the file as a value, so we’ll need to deserialize that into something a bit more usable:

var jsonSettings = JsonConvert.DeserializeObject<StyleSettings>(_configuration[$"{siteName}.json"] ?? string.Empty);

And there we go; we’ve access to Configuration values on a per-site basis.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Greg Jeffers, Senior Technical Consultant

Greg Jeffers is a Senior Technical Consultant with Perficient. He has been developing software on the Microsoft stack for 20+ years and working with Optimizely for 5. Having been in several roles across multiple industries, Greg brings a holistic approach to development. He is passionate about finding the right balance of people and processes to make users feel comfortable in the application while being performant.

More from this Author

Follow Us