Overall Architecture
In these sections of the nopCommerce Developer Documentation, we will broadly cover the overall architecture of nopCommerce. Detailed descriptions of each component will be described in later sections of the developer guide. Note that this part is an introductory overview. A more detailed discussion will come later in the guide. Depending on your experience level, these overviews may be enough to get you going!
Dependency Injection and Type Discovery
nopCommerce uses Autofac as its Dependency Injection (DI) container. Constructor injection is one of the greatest benefits of the DI container. It is used to great effect in controller constructors and plugin constructors. If the constructor for your plugin/controller needs an instance of a particular service class, you just add it to the constructor signature without worrying about breaking anything. Nor do you need to worry about the dependencies for the services themselves; The DI container will figure it all out and hide all that plumbing. Although it's not code that a developer would normally look at, almost all of the mappings either happen in PresentationNop.Web.FrameworkDependencyRegistrar.cs, or will occur in plugins. The heart of a typical mapping looks like this:
builder.RegisterType<CategoryService>().As<ICategoryService>();
The above line says tells Autofac (the "builder") to construct CategoryService
whenever an ICategoryService
is asked for. Services (CategoryService
, CustomerService
) are registered in this way, as are various “contexts” (WorkContext
, StoreContext
, etc). So dependency injection is one method by which types are "glued" together at runtime. Another method is type discovery via reflection. For example your custom event consumers (that implement IConsumer<>
) are automatically discovered so that your classes can be notified of events in the application. Basically, all the types in the assembly are looped through to find "interesting" types. This discovery occurs deep in the guts of nopCommerce (LibrariesNop.CoreInfrastructureAppDomainTypeFinder.cs). Once discovered, these types are then registered with Autofac. Other types that are treated this way include IRouteProvider
's (for your plugins' routes), and IStartupTask
's (for your plugins' one-time startup tasks), IPermissionProvider
's, and IShipmentTracker
's (I don't have experience with these last two).
Interesting reading/terminology
Composition root - The single place where all mappings come together is called the Composition Root. By necessity, the code that does this has to be aware of pretty much ALL the types in your application! Inversion of control pattern - https://msdn.microsoft.com/en-us/library/ff921087.aspx Martin Fowler’s SOLID Principles – The Dependency Inversion Principle is a core part of the SOLID design principles.