Promoting SoC Through Application Layering

Creating a layered design in an application is a fundamental element of modern software architecture. The goal is to promote the Separation of Concerns (SoC) design principle. Separation of Concerns The ideas behind SoC date back to Dijkstra's 1974 paper "On the role of scientific thought" . In computer science, separation of concerns (sometimes abbreviated as SoC) is a design principle for separating a computer program into distinct sections. Each section addresses a separate concern, a set of information that affects the code of a computer program. A concern can be as general as "the details of the hardware for an application", or as specific as "the name of which class to instantiate". A program that embodies SoC well is called a modular program. Modularity, and hence separation of concerns, is achieved by encapsulating information inside a section of code that has a well-defined interface. - Wikipedia SoC is a broad design principal th...

Using Sass in ASP.NET

Sass is an important tool that makes styling modern web applications more flexible. If you are unfamiliar with Sass, you can find plenty of information at sass-lang.com. To take advantage of Sass with Visual Studio 2022, we first need to install the Web Compiler 2022+ tool from the Visual Studio Marketplace. This example will also use the Bundler & Minifier 2022+ tool and NPM.

We'll use a simple ASP.NET Core Web App project to demonstrate a Sass implementation. We'll be hosting Javascript libraries in this project, so if you are unfamiliar with that, please refer to the earlier blog post Hosting Javascript Libraries in ASP.NET Applications.

Application Screenshot with Cerulean ThemeApplication Screenshot with Quartz Theme
Configuration

Let's configure the application to support Sass for Bootstrap using NPM (you can use different package managers and instructions can be found here). Open a Visual Studio Developer Command Prompt and navigate to the UI project, then run:

npm install bootstrap@5.3.3
npm install jquery@3.7.1
npm install del@7.1.0
npm install gulp@5.0.0

Now create an Scss folder in our project that will contain the Sass files (Sass files have an extension of .scss). We should configure the gulpfile.js to copy our Javascript dependencies to the wwwroot folder as in the Hosting Javascript Libraries in ASP.NET Applications post.

Visual Studio Solution Screenshot

For now, let's delete the wwwroot/css, wwwroot/js, and wwwroot/lib directories from the project. We'll rebuild those using the packages we downloaded with NPM.

Theme Implementation

For this example, we will use the Cerulean and Quartz themes from Bootswatch. From the Cerulean dropdown, download the _variables.scss and _bootswatch.scss files and save them in our project in a Scss/Cerulean folder (do the same for Quartz if you want).

Bootswatch Screenshot

Now we have the necessary infrastructure in place to implement a Bootswatch theme. Let's create a DefaultTheme.scss in our Scss folder and configure our theme. The general theme configuration is accomplished by the three lines below, we import the theme variables, then import Bootstrap's Sass file, then import the theme's Sass file.

@import "./Cerulean/_variables.scss";
@import "../node_modules/bootstrap/scss/bootstrap.scss";
@import "./Cerulean/_bootswatch.scss";

To switch to the Quartz theme, just replace Cerulean above with Quartz.

At this point, we're ready to utilize Web Compiler 2022+ to compile our DefaultTheme.scss into a .css file. Right-click DefaultTheme.scss and select "Web Compiler", then "Compile file".

Visual Studio Webcompiler Screenshot

The default settings will compile the .scss file into a .css file in place, meaning it will be in the same directory as the .scss file. That's not what we want. There should now be a file in the project named compilerconfig.json. Open that file, and update the outputFile location as follows:

[
  {
    "outputFile": "wwwroot/css/DefaultTheme.css",
    "inputFile": "Scss/DefaultTheme.scss"
  }
]

At this point, delete the DefaultTheme.css file that we just generated (in the Scss directory), then right-click DefaultTheme.scss and select Re-compile file. This time, it should output a DefaultTheme.css file in the wwwroot/css folder, which is where we want it. Open the Task Runner Explorer and execute the Gulpfile.js default task (if you don't have a gulpfile.js, refer to Hosting Javascript Libraries in ASP.NET Applications). We should now have everything we need in the wwwroot folder.

Now we need to update our application to load the new libaries we downloaded with NPM and load the new DefaultTheme.css file that was created. Let's modify Pages/Shared/_Layout.cshtml. In the head section, the only stylesheet it should reference is the new DefaultTheme.css, as follows:

<link rel="stylesheet" href="~/css/DefaultTheme.min.css" asp-append-version="true" />

Note that the code above references the minified version of the DefaultTheme.css, which will be created if you have the Bundler & Minifier tool installed.

Also, the only Javascript references should be:

<script src="~/lib/jquery/jquery.min.js"></script>
<script src="~/lib/bootstrap/js/bootstrap.bundle.min.js"></script>

When you run the application, it should use whichever theme you configured in the DefaultTheme.scss (Cerulean, Quartz, etc). Remember that you have to compile the DefaultTheme.scss with the WebCompiler tool for changes to take effect. This should happen automatically when you save the file, but it doesn't always. You can also configure WebCompiler rules in the Task Runner Explorer in Visual Studio. Finally, the Bundler & Minifier tool should create a .min.css version of the DefaultTheme.css file.

This example was created using Visual Studio 2022 running an ASP.NET Core Web App project in IIS Express.

Source code: https://github.com/jharrell-bits/SassDemo