In my opinion, NopCommerce is the best ASP.net store available right now. I have been working with it a lot lately. As I dug into the source code a picture of the architecture started emerging and I thought I'd post it here for my own reference as well as others'. These are my own thoughts and I don't claim that they represent the absolute truth.
First of all, let me list the top level layers. NopCommerce code can be divided into the following layers:
- Store Front (NopCommerceStore)
- Business Logic
- Data Access
Another conceptual layer is "Install". I will talk about that as well.
Store front is the main application. Apart from the application configurations and all that encompasses being an ASP.net application, it contains numerous views.
Root.master is the top level master page that defines the look and feel of the NopCommerce web store. It contains the header, footer and other top level elements. All other master pages derive from it. The other master pages are:
These pages represent the one column, two column and three column structure of the view respectively. Depending on what layout is required for a page, appropriate master page is used. For example, home page has a three column structure and account page has a two column structure.
Individual pages derive from one of these three master pages. Individual pages make heavy use of User Controls. These controls are located in the Modules folder.
The product and the category pages make use of templates. Templates define what kind of content view is presented for a particular product or category. These templates are located in the Templates folder. There are templates for Manufacturer and Payment as well but I have not dealt with them so far.
NopCommerce comes with a couple of preinstalled themes. These are called darkOrange and nopClassic. Themes, of course, provide a way of customizing the look and feel of your application. You can find themes under the App_Themes folder. The most import file in a theme is sytles.css. If you want to tweak the look and feel of NopCommerce then this is the file you will need to deal with most.
There are a lot of pages in NopCommerce that allow administering the store and are only available to the admin users. A lot of the customization can be done by just configuring NopCommerce using these admin pages (try to use these settings as much as possible before you start changing the code). These views are located under the Administration folder. Most pages here use main.master as the master page. I didn't mention main.master with the other master pages because those are the ones you will be dealing with most. Since admin pages are not visible to end users, there is less incentive to customizing the look and feel of these pages. The admin pages that come bundled with NopCommerce do a pretty good job as is.
Configuration is defined in the file named web.config. This file defines the top level configuration of your application. It references two other config files:
- ConnectionString.config – Defines the connection to database
- URL rewriting.config – Defines the URL structure of pages that represent individual entities such as product, category and manufacturer.
There is a lot of stuff going on in web.config. Of particular importance is the NopConfig section, that defines the schedules tasks, and the membership section. I will hopefully discuss these in a later blog post.
BusinessLogic project is located under the solution folder named Libraries. This is the project where most of the interesting logic stuff resides. The Store Front has the view and basic controller; wherever it requires complex logic or data access it delegates that to business logic. Another way of thinking is that Business logic is the core which Store Front builds upon. All the core data structures and services are defined here.
IoC & Services
Services encapsulate most of the business logic in a very neat way. For Example, ProductService provides means of accessing and modifying data about products. Similarly, CategoryService provides a way of accessing and modifying categories. These services are built upon interfaces and registered with a central dependency injection framework called Unity. A good place to get an understanding of the structure is to look at the ConfigureContainer function in UnityDependencyResolver. I am copying below just a couple of lines from there to give you a taste of things:
container.RegisterType<IOnlineUserService, OnlineUserService>(new UnityPerExecutionContextLifetimeManager());
container.RegisterType<ISearchLogService, SearchLogService>(new UnityPerExecutionContextLifetimeManager());
What is happening here is that IOnlineUserService interface is being associated with the concrete class OnlineUserService. The dependency injection framework takes care of resolving the dependencies to create an instance when required. All that is required to use a service is to ask the inversion of control (IoC) component for it, basically call IoC.Resolve<TypeOfService>().
NopCommerce provides plugin architecture for various providers such as Payment, Shipping and Tax. This architecture provides a clean and scalable way of adding support for new payment and other provider services. Unfortunately, there is no pluggable way of importing product data into the application but it is not hard to extend NopCommerce to create that mechanism. I plan to blog about that in a later post.
NopCommerce uses the entities framework to connect to the database. The database schema is defined in the NopModel.edmx file. It is instructive to look at this file in the designer view. There are a lot entities in the schema, most important of which is perhaps the Product entity. I find it useful to start from there and see the connections spiraling outwards. This file also defines the mapping between database entities and the business logic data structures. E.g. the Product data structure is mapped to the Products table in the database. Entities framework makes it really easy to access and modify data, as one only needs to deal with objects. The service layer makes life even easier. To add a new product for example all that is required is to call InsertProduct on the product service.
The install scripts make is very easy to set up a working NopCommerce system quickly. Installation mainly involves setting up the database. This is done using the following sql scripts:
This script creates the various tables in the database
This script sets up all the data that is required for running NopCommerce e.g. the default values of settings, localization resources, list of languages, locations, providers etc. Basically everything except information about the products to sell.
This script creates any sample data that comes with NopCommerce. This is a good aid while learning NopCommerce but in real use you would mostly want to replace it with a different mechanism to get your data in.
In this post I have tried to provide a top level picture of NopCommerce architecture. There are many details that I haven't mentioned here but once you have an idea of the architecture it is really easy to drill down into individual details. NopCommerce source code is quite modular and hence is easy to understand.
Footnote: I am quite impressed by the NopCommerce code base. The only things that I find less than likeable are the lack of unit tests and length of some functions. Apart from this, NopCommerce source code is a pleasure to work with.