 Hi there, I'm Steve Smith, aka Ardellis, I'm a Microsoft MVP and in this short video I'm going to introduce you to the eShopOnWeb reference application that I helped maintain for Microsoft, which you'll find on GitHub. To get started, the first thing you'll want to do is download the code from the GitHub repository. Navigate to github.com slash .net-architecture slash eShopOnWeb and then click the green button here to either clone or download a zip file of the source. I'm going to go ahead and clone this to my local computer. If you download the zip, just extract it to a folder. If you click this icon, it will copy the URL you need. Now we can clone the repository to our local computer using the git clone command from a terminal. Paste in the URL that we copied from the website. After a moment we have all of the source code on our local machine, we can change directory to the eShopOnWeb folder and view the contents. Now it's time to open the eShopOnWeb.sln solution file using Visual Studio for Mac. The first thing you probably want to do is run the application and verify that it works. There is one small change we'll probably have to make in order to get it working the first time that we run it. The error in this case is that the web project is not configured for development mode. Just click on it and choose the options menu and go to its run configuration and change the value of the environment variable ASP.NET Core underscore environment from production to development. Then rerun the application. Now you can see the application runs as expected. In development mode, the application uses an in-memory database for its collection of products and all of its other persistence needs. The eShopOnWeb is a fully functional online store that you can use to purchase .NET branded apparel and other items. The main page features a catalog of different products that you can add to your basket or view more information about and it supports both paging and filtering. The system also supports authentication. You can log in using a demo user account that's specified on the page. Once you're logged in, you'll see some additional options at the top of the screen. You can view your orders, you can adjust your account or you can log out. There's also a shopping basket icon here at the top right. As we add items to our basket, you can see that it continues to get updated with the number of items in it. On the basket page itself, we can change quantities of items or remove them and then we can check out to complete our order. Checking out does not involve any form of payment because this is just a demo app. Once we've placed a couple of orders, we can go and view our collection of orders here and see the details of each one of these orders. The application also includes a variety of different tests including unit tests, integration tests and functional tests. We can run these tests from within Visual Studio for Mac to verify that the application caves as it should. As you can see, all the tests ran successfully. Now let's explore the solution structure for this application and then see how a typical request is handled. The application is composed of three different projects that run in production. These are the web project, which is the user interface and front-end project. Then the infrastructure project and the application core are used behind the scenes to provide the low-level plumbing code and high-level business rules for the application. The application core is the core of the entire app. All the other dependencies in the system depend on it. So if you look at its dependencies, you'll see that it only has dependencies on a few NuGet packages and the .NET SDK itself, but not on the other projects. If you examine infrastructure, you'll see it depends on core. And likewise, web has dependencies on both core and infrastructure. We'll talk more about what goes in each of these projects in just a moment. For now, let's quickly review how a request gets served by the web application. This application takes advantage of both controllers and razor pages to serve different parts of the application. The home page is a razor page, index.cshtml. The first thing that happens when a request is made to the web application's home page is the handler onget will be called. We're going to add a breakpoint so that we can see what happens as this request is processed, and then we'll start the debugger. This razor page uses dependency injection to get a catalog view model service, which it then uses to fetch the catalog items. The catalog view model service is defined inside of the web application because it's an application-level service and it returns a view model type. The system uses caching, and so the first thing that gets hit is the cached catalog view model service. It will use a cache key that it creates based on the contents of the query string for this page. That includes the page it's on, the number of items per page, the brand, and the type that are used as filters on this application. When the item is not in the cache, it'll call into another instance of this catalog view model service. This one actually will perform the work of fetching the data. Now we've drilled down into the catalog view model service inside of the cached wrapper. This will use what's called the specification pattern to determine how it's going to query for the data that it needs from a repository. Once the specifications have been created, they are used in calls to the item repository to get both the list of items and the total number of items. Once the data has been fetched, it is placed inside of a new instance of the catalog index view model, which, once it's completely configured, is returned back to the page. Once the on-get method has completed, it will return the actual razor view with the catalog view model attached to it. The razor side of the razor page is simply razor data just like you would use inside of an MVC view, and it includes a few different controls for displaying the data. Here you can see that we're using tag helpers for the select drop-down lists for the filters, and then we're also taking advantage of similar partials to use for the pagination controls. The product details for each individual product are also a partial. The partials are defined inside of the shared folder here. So there you can see pagination and product partials. Just like with MVC or razor pages, there's also shared components for the view layout. In this case, the shared layout is coming from the views folder in its shared folder, and that is where the header and footer and other parts of the page are coming from. If you need to make a change to this application, you just need to figure out where the entry point is for the app, and this is usually pretty straightforward based on the URL. If it's a razor page, its URL is going to correspond to the path under the pages folder. So if it's the home page, it'll be the index.cshtml. If it's the privacy page, it'll be this privacy.cshtml, etc. Inside of the basket, you'll see that there are methods for checkout and index. So if you go to slash basket, it'll hit the index page, or slash basket slash checkout, will hit the checkout page. Now, because the sample application is meant to show both MVC and razor pages styles of development, there is also a controller that's used for the orders. So when a user navigates to the my orders page, that's going to correspond to the my orders action on the order controller. This in turn will have a view and a views folder called my orders. We'll see in a later video how we can modify some of this information as part of an update to this system. That provides a good overview of the web project. Let's quickly look at what goes into the application core and infrastructure projects. The application core project defines the abstractions and entities or business objects that we're going to use for this application. The entities may be grouped into things called aggregates, which should be saved or retrieved from persistence as a unit. This means that when we fetch a basket, we don't just grab the basket itself, the header essentially, but we also grab all of its children, all the basket items that are inside of that basket. Likewise, looking at an order, an order has a collection of order items with it, along with related things like an address to which it was sent. Not everything needs to be inside of an aggregate. There are also smaller entities like catalog brand and catalog item that are just simple lookup data that can stand alone. Application core is also where we're going to define our abstractions that other parts of our application will implement. These are interfaces, such as the iAsync repository, iBasket service, iOrderService, et cetera. We may define certain services inside of application core. The way that you can determine whether or not a service belongs here is primarily whether it has to do with direct knowledge of infrastructure, like the database or web services, or direct knowledge of how the user interface works, like a view model. If it doesn't need either of those things, then it's probably a good candidate to go in the application core project. However, if it needs to know about view-related stuff, it should probably go in the web project. And if it needs to know about infrastructure concerns like persistence, it should probably go in the infrastructure project. We also have a collection of specifications. These specifications are query objects. They basically define how a query is going to get executed in persistence. So when we go to fetch a basket with its items, instead of having to put those query details inside of the user interface project, our web project, we can define those inside of its own class, which we're going to call some sort of specification. And then we can write tests for this class independent of the rest of the system to verify that it's correct. Now let's move on to the infrastructure project. Inside of the infrastructure project, you'll find that there are several folders for data, identity, logging, and services. Inside the data folder is where we define our entity framework, DBContext. We have a catalog context that has DB sets for baskets and orders and related things. These are configured by individual configuration classes inside of the config folder. So if you want to see how address is mapped to the database or what type of column width it's expecting, you can look at the address configuration class to find that. This project supports migrations that will update the database as we change the properties of our entities. And so these migrations live inside this folder as well. This is also where we define our EF repository. This is an asynchronous repository implementation that uses a DBContext to fetch the items. This particular implementation of a repository leverages the specification pattern for doing its querying. So you'll find that the lists and count methods each take a specification to perform their work. And there is a specification evaluator that's used to perform this logic. So inside of the specification evaluator, it will pull the criteria from the specification and use that as a where clause on the query. Likewise, it will use aggregation from the specification on the query, as well as ordering and in turn grouping and paging. The benefit of this approach is that your repository doesn't need to continue to grow as you add additional query methods to it. Instead, the repository should be fairly fixed. And what you'll change is you'll add additional specifications inside of your application core. That's the bulk of the logic inside of this project. There are also simple classes inside of logging for performing the logging. There is an email sender that sends emails in a fake manner. And then under identity, we have the necessary classes, including a separate DBContext, for supporting the identity part of the application. That's it for this walkthrough of the eShop on web. I hope you found it useful. Please go ahead and download it if you haven't already and walk through it yourself and see if you can get it to run and verify that it works for you. If you have a problem, please open up an issue with any question that you might have. And we'll be sure to help you out and get you running as soon as we can. Thanks.