Asp.Net MVC Core 1.0 can be configured to read from environment variable. This is useful especially when you have different machines for different environments such as production, stating and development. However, this set up does not work when you have one machine for different environments. For smaller businesses one machine may host both production and staging environment. For a small team of developers working on a prototype there may be only one machine for different environments to save on cost.
In this situation, configuration based on environment variable may not work. Here I will show how you can configure the project to utilize solution configuration (similar to older Asp.NET MVC where we have used various configuration files such as web.debug.config, web.release.config etc.)
1) Add configuration name and compile symbols
As shown below add required configurations in project.json. For each configuration we need to define a compilation symbol
Add the following highlighted code in Startup method of Startup.cs file. As shown here we are using compilation directives to update the type of environment programmatically.
Similar to older Asp.Net MVC, here you need to change the configuration (as shown below) before you build or publish the application.
Depending on what solution configuration you are building, the compiler directive would emit the required code. This way the code in Starup method will be modified during compile time.
Please look into image 2 once again and notice how we are adding JSON configuration file.
As shown below add required appsettings.json files. Please note the naming of the files. It should match the names specified in Startup method (see image 2) while creating the builder object.
4) Build and Test
Build your project and test it. Try publishing your project with different solution configuration and test whether the set up is really working.
5) Side notes for post-compile and pre-compile
If you ever need to run some scripts before or after compilation based on configuration, then you may utilize the following "precompile" (or "postcompile" not shown) directive available within project.json. As shown below I am running a batch file where I am passing a name of solution configuration selected. Please pay attention to %compile.Configuration%. That's how I request MsBuild to provide the name of solution configuration. That value is transferred to a batch file as a parameter.
This batch file can be used for anything. It may copy several files depending on what is being built. In my case I have app.config (shown in Image 6) file where I have database connection string. You may notice that I am using configsource. So now I need to generate connectionstrings.config and copy it to the same level where app.config is available. By this time you might have figured out that I am going to three connectoionString.config file responsible to carry connection strings for my three different solution configurations. Again this is the same approach we followed during traditional .NET development.
(Generally we specify database connection string in appseetings.json. However, I have a few legacy class libraries. It was going to take a lot to refactor them to inject configuration service as suggested in Asp.NET MVC Cor 1.0. So I was left with no option but to add connection string to app.config. This way class libraries can be provided with database connection during runtime. At this point I am not debating on what is right or wrong but the whole point here is to demonstrate how you can utilize the build processes with ASp.NeT MVC Core 1.0 and leverage what you have been doing with an older Asp.Net MVC set up so far)
As shown in the following image, I have various connectionstring.config file for various solution configurations. The file precompilescript.bat is the file where I have a logic to find required connectionstrings.<%compile.configuration%>.config and copy that as connectionStrings.config. This all happens during pre-build. That means a correct file is copied just before a build begins. During run time app.config references it and provides a correct connection string.
Asp.NET MVC Core 1.0 is quite new. The way it has been set up is very different than the traditional .NET development. It is likely that we will have to mix and match a traditional approach with a new approach for the next few years until everything we need to build a web application get transferred to this newer approach.
I hope the above mentioned work around may help.
I am also new to this kind of development approach. If you feel that you have better suggestion in context with this blog post, then please feel free to let me know. I really appreciate any opportunity to learn something new and better.
Thanks a lot for reading. Have fun with coding!!