NetLearner is an ASP .NET Core web app to allow any user to consolidate multiple learning resources all under one umbrella. The codebase itself is a way for new/existing .NET developers to learn ASP .NET Core, while a deployed instance of NetLearner can be used as a curated link-sharing web application.
Registration for each web app has been disabled by default. To enable registration, please do the following:
Locate scaffolded Identity pages under /Areas/Identity/Pages/Account/
In Register.cshtml, update the page to include environments in addition to Development, if desired.
In Register.cshtml.cs, replace [Authorize] with [AllowAnonymous] to allow access to registration
Architecture
The current version of NetLearner on Github includes a shared .NET Standard Class Library, used by multiple web app projects. The web apps include:
MVC: familiar to most ASP .NET developers
Razor Pages: relatively new in ASP .NET
Blazor: the latest offering from ASP .NET
Future updates will also include:
Web API, exposed for use by other consumers
JavaScript front-end web app(s)
Note that an ASP .NET Core web app can contain various combinations of all of the above. However, the purpose of the NetLearner application code is to demonstrate how to achieve similar results using all of the above. So, each of the web app projects will be developed in parallel, using a shared library.
Shared Library
The shared library is a .NET Standard 2.1 library. This version was selected because .NET Core 3.x supports .NET Standard 2.1, as seen in the official documentation.
Database Context: for use by Entity Framework Core
Migrations: for EF Core to manage the (SQL Server) db
Models: db entities, used by web apps
Services: service classes to handle CRUD operations
Using terms from Clean Architecture references, you may think of the DB Context and Migrations as part of the Infrastructure code, while the Models and Services are part of the Core code. For simplicity, these are all kept in a single library. In your own application, you may split them up into separate assemblies named Core and Infrastructure.
Running the Application
In order to run the web app samples, clone the following repository:
In the Package Manager Console panel, change the Default Project to “NetLearner.SharedLib” to ensure that EF Core commands are run against the correct project
In the Package Manager console, run the Update-Database command
Verify that there are no errors upon database creation
To run the samples from Visual Studio 2019:
Run each web project one after another
Navigate to the links in the navigation menu, e.g. Lists and Resources
Add/Edit/Delete items in any of the web apps
Create one or more lists
Create one more resources, assign each to a list
Verify that your data changes are reflected no matter which web app you use
What’s Next?
In 2020, you can expect a new A-Z weekly blog series to cover 26 different topics from January through June 2020. To get a sneak peek of what’s to come, take a peek at the 2019 A-Z series.
Throughout my 2018 mini-series and 2019 A-Z series, I’ve regularly kept up to date on what’s new with ASP .NET Core for building Web Apps, Web APIs and even full-stack C# web applications with Blazor!
With the 2019 release of ASP .NET Core 3.0 and the LTS follow-up ASP .NET Core 3.1, now is still a great time to be an ASP .NET Core developer. But where should you begin? You have many options.
Dev Tools for ASP .NET Core
Visual Studio for Windows: a full-fledged IDE that runs on Windows (or even on Windows on your Mac via Parallels/Bootcamp. Get the latest version to try out new stable ASP .NET features and get the Preview versions to try cool new features. Install just the pieces you need. Start with the free Community edition for students, individuals and open-source projects.
Visual Studio for Mac: build ASP .NET Core applications on a Mac in a full-fledged IDE. VS for Mac can also be used for macOS apps, Xamarin mobile apps for iOS/Android, cloud apps and more!
Visual Studio Code: super light-weight code editor available on Windows, MacOS and Linux. Use the dotnet CLI tools in the integrated Terminal to quickly build ASP .NET Core web apps and more!
Going forward, you can expect a 2020 A-Z series that will use ASP .NET Core 3.1 (LTS). The upcoming series will contain new and improved versions of the topics explored in the 2019 series, including Build 2020 coverage.
For now, this one-off blog post will discuss code-sharing for ASP .NET Core developers. For demonstrative purposes, the sample code accompanying this article includes code that is derived from the code snippets provided on the following blog:
There are multiple reasons why you may want to share code between multiple projects/assemblies.
Code reuse: This should be pretty self-explanatory. You shouldn’t have to rewrite the same code more than once. Placing reusable code in a shared library enables code reuse.
Multiple front-ends: In the sample code, there are multiple web apps, all using the same data layer. Splitting into separate assemblies allows you to develop multiple web apps in their own projects/assemblies.
Separate deployments: You can deploy each assembly independent of one another.
Even if you’re just working on a single web app (just Blazor, or a web app that combines Blazor+MVC+Razor Pages), you can still benefit from this type of “physical” code separation. Note that this approach is not required for “separation of concerns”. The nature of ASP .NET Core web applications make them possible to implement separation of concerns, even if everything is in a single project (such as the one generated by the official VS2019 project templates).
NOTE: This article will focus on the creation of a shared library project to hold a shared database context, EF Core migrations, models and services. In your application, you can go further by separating your domain objects and related items into their own project/assembly.
For an official guide on ASP .NET Core architecture, download this free ebook and its sample code. The eShopOnWeb sample includes the “business layer” with domain entities under ApplicationCore, the “data layer” with data context + migrations under Infrastucture, and the “presentation layer” with its MVC components under Web.
Quote: “Separating things by project ensures decisions about dependency direction are enforced by the compiler, helping avoid careless mistakes. Separating into projects isn’t solely about individually deploying or reusing assemblies.”
Creating a shared library
The quickest way to create a shared library project is to use the built-in project templates. Create a project of type .NET Standard 2.1 using either Visual Studio 2019 or CLI commands for use with VS Code.
To add the new project in Visual Studio 2019:
Add | New Project
Select the template for Class Library (.NET Standard)
Click Next
Name your project and select a location
Click Create
Verify that the shared library is a Class Library project targeting .NET Standard 2.1. Check out the official docs to learn more about how to pick a version of .NET Standard for your class libraries.
If using the .NET CLI, type the following command:
>dotnet new classlib -f netstandard2.1
As of .NET Core 3.0, Entity Framework Core is now available via NuGet. As a result, you must add the following packages manually.
Microsoft.EntityFrameworkCore
Microsoft.AspNetCore.Identity.EntityFrameworkCore
Microsoft.EntityFrameworkCore.SqlServer
To add EF Core in Visual Studio 2019:
In Solution Explorer, right-click your shared library project
Select “Manage NuGet Packages…”
Search for the aforementioned packages and install v3.1 for each
To create a new database context in the shared library project:
Create a “Data” folder at the root level of the project folder
In the Data folder, create a new public class named “LibDbContext” that inherits from “IdentityDbContext”
Create a “Models” folder at the root level of the project folder
In the Models folder, add one or more model classes, to be used by your web application project(s)
In the context class, add one or more DbSet<T> properties
Your shared context class LibDbContext should now look like the following snippet:
using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; using SharedLib.Models;
namespace SharedLib.Data { public class LibDbContext : IdentityDbContext { public LibDbContext(DbContextOptions<LibDbContext> options) : base(options) { }
protected LibDbContext() {
}
public DbSet<CinematicItem> CinematicItems { get; set; }
} }
In this case, the one DbSet property represents a collection of CinematicItems defined in its own CinematicItem model class file:
using System;
namespace SharedLib.Models { public class CinematicItem { public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int Phase { get; set; }
public DateTime ReleaseDate { get; set; } } }
Note that the new database context in the shared library is a replacement for any database context you may already have in your web app projects. In fact, you’ll have to edit your Startup.cs file in each web app project to ensure that it is using the correct database context.
Using the Shared Library
If you are starting a brand new web project, you can start with an auto-generated template. You could create an empty web project and add everything manually as needed. But it may be easier to start with a standard web template and remove/edit items as necessary.
To create a new web project in Visual Studio 2019:
Add | New Project
Select the template
For Blazor, select Blazor App
For MVC or Razor Pages, select ASP .NET Core Web Application
Click Next
Name your project and select a location
Click Create
Select .NET Core, ASP .NET Core 3.1, and a project template
For Blazor, select Blazor Server App
For Razor Pages, select Web Application
For MVC, select Web Application (Model-View-Controller)
For Authentication, change “No Authentication” to “Individual User Accounts”
Under Advanced, leave the checkbox checked for “Configure for HTTPS”
Following the above steps will add a new database context and an initial migration. Since we will be using our shared library instead, let’s do some cleanup in each web project you created.
In each web project, add the Shared Library as a dependency:
In Solution Explorer, right-click Dependencies for a web project
Click Add Reference under Dependencies
Select the shared library project
Click Ok
Repeat for each web project
In each web project, update the Startup.cs class:
Replace any mentions of ApplicationDbContext with LibDbContext
Expand the UseSqlServer method call to refer to the connection string and db context in the shared assembly
Perform some additional cleanup in each web project:
Delete the template-generated ApplicationDbContext class
Delete any initial migrations in the Migrations folder
In the Startup.cs class, remove any using statements that mention the .Data namespace in your web project
Add a using statement referring to the .Data namespace in your shared library project, e.g. SharedLib.Data
Make a similar change in your partial view “_ViewImports.chstml” if applicable
If you have more than one web project, use the ConnectionString value from the first appsettings.json file and reuse it in the other web app projects.
BUT WAIT: beyond any initial sample, always use app secrets during development to avoid connection strings in appsettings.json files. For Azure-deployed web projects, use Key Vault or environment variables in your App Service.
Running the Samples
In order to run the web app samples, clone the following repository:
In the Package Manager Console panel, change the Default Project to “SharedLib” to ensure that EF Core commands are run against the correct project
In the Package Manager console, run the Update-Database command
Verify that there are no errors upon database creation
To run the samples from Visual Studio 2019:
Run each web project one after another
Navigate to the Cinematic Items link in the navigation menu
Add/Edit/Delete items in any of the web apps
Verify that your data changes are reflected no matter which web app you use
NOTE: During Blazor development, editing a Razor component may not always trigger the proper Intellisense help in the containing Page. You may have to clean+rebuild solution or even reopen the solution in VS2019.
Conclusion
In this article, we covered the following:
Creation of a shared library project for use in one or more ASP .NET Core web apps
Some reasons for such an approach
Steps required to use the shared library
Sample projects to see the shared library in action