-
Notifications
You must be signed in to change notification settings - Fork 5.8k
00 Details on updates targeting .NET Core 2.0
Earlier this year, we published an eBook and sample application offering guidance for Architecting Modern Web Applications with ASP.NET Core and Microsoft Azure.
You can read more about the goals for this eBook and its initial publication here.
We have recently published updates to the eBook and sample application to bring them in line with the latest releases of ASP.NET Core 2.0 and Entity Framework Core 2.0.
This post describes some of the highlights of the changes. Note that the sample project is open source and you can contribute by filing issues (if you have questions or discover problems) and submitting pull requests.
The eBook has been updated to ASP.NET Core 2.0, .NET Standard Library 2.0 and Entity Framework 2.0 and .NET Core 2.0 in general, while referencing to the new code implemented in the updated sample app.
The sample application has been expanded to support additional functionality over what existed in the initial version. Specifically, in addition to allowing users to manage a shopping cart, log in, and check out, users can now view past orders. Orders also include shipping address data, which is implemented as a value object using the new owned entities in EF Core 2.0.
All of the projects have been updated to the ASP.NET 2.0, netstandard 2.0, and EF Core 2.0, as appropriate.
Also, the identity management system has been updated to use the latest ASP.NET Identity 2.0 version, which includes built-in support for Two Factor Authentication (2FA) using an Authenticator app.
In addition, the sample now makes use of the Specification pattern to improve the design of its data access and better follow separation of concerns. These additional application features were added to help make the sample more “real world” in nature, providing more opportunities to demonstrate new features and techniques available in ASP.NET Core.
Finally, one of the new features added in ASP.NET Core 2.0 is Razor Pages, and so the eBook and the sample application have been updated to demonstrate side-by-side in separate web projects both a Razor Pages implementation and a Controllers-and-Views implementation of the same business application.
There is great guidance on how to upgrade your apps from 1.x to 2.0 of ASP.NET Core available in the docs.
For this application, the upgrade process went relatively smoothly. One change in the design of EF Core migrations that’s worth mentioning has to do with seed data. In the 1.x version of the sample, seed data was added during the call to ConfigureServices in Startup. In EF Core 2.0, migrations load and run Startup (and thus ConfigureServices) before they create the data structures. This of course means that if you’re trying to add data during Startup, it’s not going to work since the migrations haven’t yet created the necessary data schema. This issue is easily addressed by moving your code to add seed data out of Startup – in this case into Program.cs. This has the added benefit of making it easier for your functional tests to seed data, too, without having to clutter your production Startup class with test data.
Below is the code used to add seed data:
public class Program
{
public static void Main(string[] args)
{
var host = BuildWebHost(args);
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
var loggerFactory = services.GetRequiredService<ILoggerFactory>();
try
{
var catalogContext = services.GetRequiredService<CatalogContext>();
CatalogContextSeed.SeedAsync(catalogContext, loggerFactory)
.Wait();
var userManager = services.GetRequiredService<UserManager<ApplicationUser>>();
AppIdentityDbContextSeed.SeedAsync(userManager).Wait();
}
catch (Exception ex)
{
var logger = loggerFactory.CreateLogger<Program>();
logger.LogError(ex, "An error occurred seeding the DB.");
}
}
host.Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseUrls("http://0.0.0.0:5106")
.UseStartup<Startup>()
.Build();
}
Note that the upgraded version of the app now makes use of CreateDefaultBuilder, which also builds the app’s configuration system and injects it into Startup’s constructor (rather than having the Startup constructor create it).
Using Value Objects, you can model types that are not defined by a key, like an Entity is. Two separate instances of a value object are considered equal if all of their properties are the same. Support for value objects is added through a new feature in EF 2.0, owned types. An physical mailing address is an example of a value object, since any two such addresses are considered to be the same as long as their properties (street, city, state, etc.) are all the same. In the eShopOnWeb sample, customer orders include a ShipToAddress, which is of type Address. This type is associated with the order as an owned type through the following configuration:
// builder is an instance of EntityTypeBuilder<Order>
builder.OwnsOne(o => o.ShipToAddress);
With this configuration in place, when EF Core creates the Order table in the database, it uses the following schema:
- Getting Started for Beginners (with video)
-
Walkthroughs
- Deploying to Azure App Service from Visual Studio
- Deploying to Azure App Service from Azure Portal
- Deploying to Azure App Service from Visual Studio for Mac
- Running as a Linux Container locally in Visual Studio
- Deploying as a Linux Container into Azure App Service
- Running in a Windows Container locally in Visual Studio
- Running as a Linux Container locally in Visual Studio for Mac
- Deploying as a Windows Container into a Windows Container host in Azure
- Working with the Project and Adding New Features using Visual Studio for Mac