Create ASP.NET Core MVC Project
I am using Visual Studio 2019 Community Edition, a free download from Microsoft. Starting with 2019, the wizard for choosing templates is different from previous versions, but regardless which version you have, the steps are about the same.
- Go to Create a new Project.
- Select ASP.NET Core Web Application.
- Select the name and location for the project (I called mine MultiAppDemo).
- Choose ASP.NET Core (in my case, it’s version 3.0).
- Choose ASP.NET Model-View-Controller (for simplicity sake, select No Authentication, so VS doesn’t generate artifacts irrelevant for this walk-through).
Your project view in the Solution Explorer should look something like this:
Since we used the ASP.NET MVC template and not the SPA template, we need to add Microsoft.AspNetCore.SpaServices.Extensions NuGet package. To install the package, open the Package Manager Console and run the following statement:
Install-Package Microsoft.AspNetCore.SpaServices.Extensions
Create Angular Project
Make sure you have the following software installed (all free):
- Visual Studio Code
- Node.js
- Angular CLI. To install, go to the command prompt and execute this command:
npm install -g @angular/cli
I am using Angular v8. Using an earlier version is okay as long as it has access to the createCustomElement API. Those capabilities are available in Angular v7 as well.
To create an Angular solution for use in our ASP.NET MVC project, open the command prompt and navigate to the folder that contains the project file (extension .csproj) for your MVC project. Once there, create the Angular project by executing this command from the prompt:
ng new Apps
Choose N for routing and CSS for styling.
Change directory to Apps, and type the following (including the trailing period):
code .
You should now have your Angular project opened in Visual Studio Code.
Bootstrap Angular Elements
The idea is to use this root project as a repository for re-usable components that will be available to other Angular applications (we will create them later) as normal Angular components and to the MVC views as Web Components (aka Angular Elements).
Web components are a set of web platform APIs that allow you to create new custom, reusable, encapsulated HTML tags to use in web pages and web apps.
Angular provides a way to package Angular components as web components via an API called Angular Elements. For instance, if you create an Angular component that shows the current time and bootstrap this component as Angular element current-time, you can then include <current-time /> tag in plain HTML pages.
Open your Angular project in VS Code. Open a terminal window and type a command to generate the clock component and to add that component to app.module.ts:
ng g c current-time
You should now have a folder called current-time under src/app with several files that make up your clock component. Change your app/current-time/current-time.component.html to have the following markup:
<p>{{ time }}</p>
Change your app/current-time/current-time.component.ts to have the following code:
import { Component, OnInit, OnDestroy } from '@angular/core';
@Component({
selector: 'app-current-time',
templateUrl: './current-time.component.html',
styleUrls: ['./current-time.component.css']
})
export class CurrentTimeComponent implements OnInit, OnDestroy {
timer: any;
time: string
constructor() { }
ngOnInit() {
var setTime = () => {
var today = new Date();
this.time = ("0" + today.getHours()).slice(-2) + ":" +
("0" + today.getMinutes()).slice(-2) + ":" +
("0" + today.getSeconds()).slice(-2);
};
setTime();
this.timer = setInterval(setTime, 500);
}
ngOnDestroy(){
if (this.timer){
clearTimeout(this.timer);
}
}
}
The implementation is rather simple. We have a timer that fires every half a second. The timer updates the time property with a string representing the current time, and the HTML template is bound to that string.
Paste the following styles into your app/current-time/current-time.component.css
p {
background-color: darkslategray;
color: lightgreen;
font-weight: bold;
display: inline-block;
padding: 7px;
border: 4px solid black;
border-radius: 5px;
font-family: monospace;
}
Now, save all the modified files and let’s bootstrap this clock component as a web component:
- Open a new terminal window inside Visual Studio Code.
- Add Angular Elements libraries and polyfills. To do that type the following command at the terminal window:
ng add @angular/elements
- Navigate to src/app/app.module.ts
- If it’s not there already, add the following import statement at the top of app.module.ts:
import { createCustomElement } from ‘@angular/elements’; - Add Injector to the import from @angular/core:
import { NgModule, Injector } from ‘@angular/core’; - Replace bootstrap: [AppComponent] with
entryComponents: [ClockComponent] - Lastly, add the constructor and ngDoBootstrap to the AppModule class.
constructor(private injector: Injector) {
}
ngDoBootstrap(){
customElements.define('current-time', createCustomElement(CurrentTimeComponent,
{injector: this.injector}));
}
There is one more thing we need to do now that will be necessary later when we try to import CurrentTimeComponent in a different Angular application. We need to export this component from the module. To do that, add the exports property just above providers:
exports: [
CurrentTimeComponent
],
Your entire app.module.ts should look like this:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Injector } from '@angular/core';
import { AppComponent } from './app.component';
import { createCustomElement } from '@angular/elements';
import { CurrentTimeComponent } from './current-time/current-time.component';
@NgModule({
declarations: [
AppComponent,
CurrentTimeComponent
],
imports: [
BrowserModule
],
exports: [
CurrentTimeComponent
],
providers: [],
entryComponents: [CurrentTimeComponent]
})
export class AppModule {
constructor(private injector: Injector) {
}
ngDoBootstrap(){
customElements.define('current-time', createCustomElement(CurrentTimeComponent,
{injector: this.injector}));
}
}
Now, let’s test that our solution works. Go to src\index.html and replace <app-root></app-root> with <current-time></current-time>. Type ng serve –open from the terminal window to run the project. You should now see the current time showing in your browser.

Use Web Components in ASP.NET Project
The next step is to make our current-time component available in the ASP.NET MVC Core Project. To do that, open the ASP.NET project in Visual Studio. Paste the following code before the closing </body> tag in Views/Shares/_Layout.cshtml
<environment include="Development">
<script type="text/javascript" src="http://localhost:4200/runtime.js"></script>
<script type="text/javascript" src="http://localhost:4200/polyfills.js"></script>
<script type="text/javascript" src="http://localhost:4200/styles.js"></script>
<script type="text/javascript" src="http://localhost:4200/scripts.js"></script>
<script type="text/javascript" src="http://localhost:4200/vendor.js"></script>
<script type="text/javascript" src="http://localhost:4200/main.js"></script>
</environment>
<environment exclude="Development">
<script asp-src-include="~/Apps/dist/core/runtime-es2015.*.js" type="module"></script>
<script asp-src-include="~/Apps/dist/core/polyfills-es2015.*.js" type="module"></script>
<script asp-src-include="~/Apps/dist/core/runtime-es5.*.js" nomodule></script>
<script asp-src-include="~/Apps/dist/core/polyfills-es5.*.js" nomodule></script>
<script asp-src-include="~/Apps/dist/core/scripts.*.js"></script>
<script asp-src-include="~/Apps/dist/core/main-es2015.*.js" type="module"></script>
<script asp-src-include="~/Apps/dist/core/main-es5.*.js" nomodule></script>
</environment>
The previous code segment shows two blocks, one for development and one for non-development. When we are in development, our Angular project that hosts web components will be running on port 4200, started from VS Code. When we are in production, the Angular project will be compiled into wwwroot/apps/core folder with javascript files named with hashes appended. In order to properly reference the files, we need to use asp-src-include tag helpers.
Next, in _Layout.cshtml, add <current-time></current-time> right after the </main> closing tag.
To test that our development configuration works:
- Go to VS Code where your Angular project is opened, and type this command at the terminal prompt: ng serve –liveReload=false
- Go to Visual Studio where your ASP.NET project is opened and hit F5 to run the project.
Your ASP.NET site should open up and you should see the current time component displayed on every page.