In this article, we consider the stack of technologies used in nopCommerce, the most popular ASP.NET shopping cart in the world. nopCommerce has been developed and supported by professionals since 2008.
We, the nopCommerce team, always try to keep nopCommerce running on the latest technologies to offer the best experience possible to our users. That's why nopCommerce is the leading ASP.NET-based open-source eCommerce platform for now.
nopCommerce is a fully customizable shopping cart, stable, secure, and extendable. From downloads to documentation, nopCommerce.com offers a comprehensive base of information, resources, and support from the nopCommerce community.
nopCommerce version runs on .NET Core. Since it's cross-platform it can be run on Windows, Linux, or Mac OS. nopCommerce also supports different database types. So let's start by describing the data access layer.
Databases
On the Data access layer, you are allowed to use Microsoft SQL Server, MySQL, and PostgreSQL as backend databases.
- SQL Server is Microsoft's full-featured relational database management system.
- MySQL is the world's most popular open-source database. With its proven performance, reliability, and ease of use, MySQL has become the leading database choice for web-based applications.
- PostgreSQL is a powerful, open-source object-relational database system with over 30 years of active development that has earned a strong reputation for reliability, feature robustness, and performance.
The possibility to use all these databases is coming out of the box so you don't need lots of extra configuration to set this up.
If you look at the source code, you see the appropriate data providers: PostgreSqlDataProvider, MySqlDataProvider, MsSqlDataProvider in the Nop.Data project.
Redis
Next, nopCommerce uses Redis. As you may know, Redis is an open-source, in-memory data structure store, used as a database, cache, and message broker. Redis is applied to distributed applications, for example, with web farms scenarios. Using Redis allows us to store old data as an in-memory cache dataset. This approach significantly boosts the speed and performance of the application.
This is the piece of code from the appsettings.json file that allows you to set up Redis in nopCommerce:
"DistributedCacheConfig": {
"DistributedCacheType": "redis",
"Enabled": false,
"ConnectionString": "127.0.0.1:6379,ssl=False",
"SchemaName": "dbo",
"TableName": "DistributedCache"
},
There are also another distributed cache types you can choose from:
This screenshot represents the distributed cache settings from the admin area -> App settings page.
Microsoft Azure
The next noteworthy technology that nopCommerce uses is Microsoft Azure. Azure is a public cloud computing platform with solutions including Infrastructure as a Service (IaaS), Platform as a Service (PaaS), and Software as a Service (SaaS) that can be used for services such as analytics, virtual computing, storage, networking, and much more. nopCommerce can be deployed on Azure using FTP, Visual Studio web deploy, or using Web platform installer.
Azure supports multiple instances of nopCommerce. It's great for any application scalability. Using this feature, you may not worry whether your site can handle a large number of visitors. Azure also allows us to use BLOB storage, distributed caching, and session management support.
This is the piece of code from the appsettings.json file that allows you to set up Azure BLOB storage in nopCommerce:
"AzureBlobConfig": {
"ConnectionString": "",
"ContainerName": "",
"EndPoint": "",
"AppendContainerName": true,
"StoreDataProtectionKeys": false,
"DataProtectionKeysContainerName": "",
"DataProtectionKeysVaultId": ""
},
It can also be set up from the admin area:
This screenshot represents the Azure BLOB storage settings from the admin area -> App settings page.
Business logic
Then, let's discuss the technologies we use in the nopCommerce Business logic layer.
Linq2DB
First of all, it's LINQ to DB, which is the LINQ database access library offering a simple, light, fast, and type-safe layer between objects and the database. In other words, it enables us to work with a database using .NET objects. It can map .NET objects to various numbers of database providers. You may choose between MS SQL Server, MySql server, and PostgreSQL.
So, LINQ to DB is kind of a bridge between the Business Logic layer and the Data layer.
If we analyze the code, we can easily find that each database is supported by its own class that implements the INopDataProvider interface and depends on the Linq2DB library:
Also, note that all work with table data is carried out through the IRepository
This approach commits us to control the creation of the table in the database.
FluentMigrator
To control the creation of the database objects we use the FluentMigrator
library. FluentMigrator
is a migration framework for .NET. Migrations are a structured way to alter the database schema and are an alternative to creating lots of SQL scripts that have to be run manually by every developer involved. Migrations solve the problem of evolving a database schema for multiple databases. For example, the developer's local database, the test database, and the production database. Database schema changes are described in classes written in C# that can be checked into a version control system.
To see how we use FluentMigrator
in the code, open the CategoryBuilder class which represents the Category entity configuration for the database:
As a parameter of the MapEntity method, you can see the CreateTableExpressionBuilder class, which is the FluentMigrator
class that allows us to apply special rules for entity mapping when creating this table.
Then, let's open the DataMigration class:
This class inherits from the abstract Migration class. You can create your own migrations which should also be derived from this abstract class.
So, as you can see, we use this class to migrate data from one version of nopCommerce to another. This way we add new records, new columns, or even delete columns. We also have such migration classes to migrate settings and local resources. In the past nopCommerce versions, we used SQL upgrade scripts to apply such changes to the database, which wasn't as handy as it is now.
Now, using the FluentMigrator
library allows us to simplify the migration process to any database framework.
AutoMapper
The next library, which is introduced in this article, is AutoMapper
. AutoMapper
is a simple library that helps us to transform one object type to another. It is a convention-based object-to-object mapper that requires very little configuration. We need this library, for example, when it comes to retrieving entities from the database and populating the appropriate models.
To illustrate it, we open the StoreController
of the admin area. Here we find the Edit()
method which returns a view enabling a Store editing. In this method, as you can see, we retrieve the store from the database first:
Then, in the PrepareStoreModel()
method there is just one line that maps the entity to a new model:
This is exactly why we need AutoMapper
.
At the same time, in the AdminMapperConfiguration
we have already configured how exactly the store entity should be mapped to the model:
Fluent Validation
The next library we discuss is Fluent Validation. It's a validation library for .NET that uses a fluent interface and lambda expressions for building validation rules. We need validation to ensure that data inserted satisfies defined formats and other input criteria during customer registration, creating and updating products and categories in the admin area, adding blog posts, etc.
Let's look closer. For example, the RegisterValidator
class sets validation rules for RegisterModel
which is used for customer registration:
In this class we see a rule saying that the Email field should not be empty, but if it is, the validator returns the "required" message to a customer. In addition, an inserted email should also match the email address criteria.
There are many other validation rules in this file.
ASP.NET Core internal dependency injection
As you may know, nopCommerce supports the dependency injection software design pattern, which is a technique for achieving Inversion of Control between classes and their dependencies. It allows nopCommerce to stay easy modifiable as it grows in size and complexity.
To achieve this we use the built-in ASP.NET Core internal dependency injection.
To illustrate the dependency injection in the code, let's look, for example, at the ProductService class:
Here we have many dependencies going into the constructor. If we look at the implementation of one of those dependencies, for example, at the CustomerService
we see that it contains a bunch of dependencies as well:
And to resolve these dependencies we create the DependencyRegistrar
class where the AddScoped()
method registers such services as ProductService
, CustomerService
, and others:
So, using the ASP.NET Core internal dependency injection, we have a service container that takes on the responsibility of creating an instance of the dependency and disposing of it when it's no longer needed. And we can easily inject the service into the constructor of the class where it should be used.
Autofac
We also use the Autofac
library which is an addictive Inversion of Control container for .NET. Autofac is one of the libraries we use right now, but, it's important to say, we use this library to only wrap the built-in Dependency Injection container from ASP.NET Core. That's why you can find out that the only file where we access the Autofac namespace is the Program class:
Look at the Main method where we override the factory used to create the service provider.
User interface
Further, let's see which libraries we use in the User interface layer.
Razor View Engine
Razor View Engine allows us to embed server-based code into web pages to produce HTML.
Let's look at the category page view:
Razor enables us to easily render the category name and to render the details like the description. It processes considering conditions, such as if the description is not empty we render the appropriate HTML code.
Using Razor we can also iterate and display subcategories or featured products.
jQuery
We also use jQuery which is a javascript library used to extend the UI&UX functionality of HTML pages. You can find the appropriate javascript files in the "js" folder in wwwroot:
jQuery DataTables and more
In addition, particularly, to display the data in tables in the admin area we use a DataTables plug-in for jQuery. Such tables look like this:
We also use a lot of other jQuery plugins so we don't need to reinvent the wheel and can concentrate on things that matter.
- View in ASP.NET MVC
- How to bind a model to a partial view in ASP.NET MVC?
- How to define a custom action selector in ASP.NET MVC?
- How to display an error message using ValidationSummary in ASP.NET MVC?
- How to enable client side validation in ASP.NET MVC?
- How to enable bundling and minification in ASP.NET MVC?
- How to pre-compile razor view in ASP.NET MVC?
- How to set image path in StyleBundle?
- What is RouteData in ASP.NET MVC?
- Difference between Html.RenderBody() and Html.RenderSection() in ASP.NET MVC
- Difference between Html.Partial() and Html.RenderPartial() in ASP.NET MVC
- How to use web.config customErrors in ASP.NET MVC?
- How to display a custom error page with error code using httpErrors in ASP.NET MVC?
- How to create a custom filter in ASP.NET MVC?
- Redirect non-www to www domain in ASP.NET
- Redirect from HTTP to HTTPS in ASP.NET
- How to upload files in ASP.NET MVC?