NopCommerce Architecture Analysis of Autofac Dependency Injection Class Generation Container

  • 2021-07-16 02:16:18
  • OfStack

NopCommerce uses IOC framework: Autofac to achieve the purpose of loosely coupled framework design. According to some people's tests, Autofac is an IOC tool with good performance.

1. In IOC, components need to be registered in IOC first, and some are registered through configuration files. Like Spring. net, there are also registered through features, like StructureMap, and there are also registered through agents, like Autofac. However, IOC pays attention to one principle, that is, the separation of interface and implementation. All IOC is the life of a concrete class that implements an interface. Then, when in use, the system gets the implementation class of the interface from IOC and creates the object.

2. Let's look at how NopCommerce uses Autofac to realize loosely coupled framework design. In fact, its plug-in mechanism is also implemented through Autofac.

The encapsulation and flexible use mechanism of IOC is mainly encapsulated in Nop. Core. Infrastructure. In Autofac, objects are also called components. Component lifecycle is divided into singleton, temporary and lifecycle domains, which are defined as follows:


namespace Nop.Core.Infrastructure.DependencyManagement 
{ 
 public enum ComponentLifeStyle 
 { 
  Singleton = 0, 
  Transient = 1, 
  LifetimeScope = 2 
 } 
} 

Autofac has containers and provides methods to register interfaces and their types, methods to find registered types, and automatic creation of objects.

3. Type finder

In order to support plug-in functions and support 1 automatic registration functions. The system provides a type finder. ITypeFinder and implementation classes provide this functionality. The Type Finder allows you to find classes in this program domain or all DLL classes in the entire bin directory and register them in the Type Inversion Container. ITypeFinder and its implementation classes are as follows:

4. Type registration

Container management class: ContainerManager, which manages containers generated by Autofac;

Container Configurator: ContainerConfigurer: Configure the dependency reversal container and establish the relationship between type dependency registration and type lookup classes for the entire framework.

There is a dependent class engine context in the system: EngineContext, which can generate an engine according to the configuration file, and this engine is responsible for returning objects from the container according to the type interface.

System default engine NopEngine, if no valid engine is configured, the default engine is used, and the generated engine is saved in the singleton container.

Their relationship is as follows:

The system initializes the engine context in the method Application_Start of class MvcApplication. And by calling EngineContext. Initialize (false); Realize the registration function of all reverse dependencies;

5. Container registration class

System registration interface: IDependencyRegistrar, the system through ContainerConfigurer registration of this interface and the implementation of the class, and through ITypeFinder class search assembly to implement the interface IDependencyRegistrar class. The code is as follows:


namespace Nop.Core.Infrastructure.DependencyManagement 
{ 
 /// <summary> 
 /// Configures the inversion of control container with services used by Nop. 
 /// </summary> 
 public class ContainerConfigurer 
 { 
  public virtual void Configure(IEngine engine, ContainerManager containerManager, EventBroker broker, NopConfig configuration) 
  { 
   //other dependencies 
   containerManager.AddComponentInstance<NopConfig>(configuration, "nop.configuration"); 
   containerManager.AddComponentInstance<IEngine>(engine, "nop.engine"); 
   containerManager.AddComponentInstance<ContainerConfigurer>(this, "nop.containerConfigurer"); 
 
   //type finder 
   containerManager.AddComponent<ITypeFinder, WebAppTypeFinder>("nop.typeFinder"); 
 
   //register dependencies provided by other assemblies 
   var typeFinder = containerManager.Resolve<ITypeFinder>(); 
   containerManager.UpdateContainer(x => 
   { 
    var drTypes = typeFinder.FindClassesOfType<IDependencyRegistrar>(); 
    var drInstances = new List<IDependencyRegistrar>(); 
    foreach (var drType in drTypes) 
     drInstances.Add((IDependencyRegistrar)Activator.CreateInstance(drType)); 
    //sort 
    drInstances = drInstances.AsQueryable().OrderBy(t => t.Order).ToList(); 
    foreach (var dependencyRegistrar in drInstances) 
     dependencyRegistrar.Register(x, typeFinder); 
   }); 
 
   //event broker 
   containerManager.AddComponentInstance(broker); 
  } 
 } 
}

The interface IDependencyRegistrar is as follows:


namespace Nop.Core.Infrastructure.DependencyManagement 
{ 
 public interface IDependencyRegistrar 
 { 
  /// <summary> 
  ///  This method is used after passing the ContainerBuilder Register dependencies.  
  /// </summary> 
  /// <param name="builder"> Container manager class </param> 
  /// <param name="typeFinder"> Type finder interface </param> 
  void Register(ContainerBuilder builder, ITypeFinder typeFinder); 
  /// <summary> 
  ///  Register sort sequence number  
  /// </summary> 
  int Order { get; } 
 } 
}

6. Singleton class container

Singleton class families hold singleton objects in the system that have the same life cycle as programs, or singleton class containers.

This includes singleton containers for entity classes, collection classes, and dictionary classes.

Singleton < T > , SingletonList < T > , SingletonDictionary < TKey, TValue > . EngineContext is through Singleton < T > Class to manage the engine.

7. MVC service provider class.

The type dependency fetcher, NopDependencyResolver, inherits the interface under mvc, IDependencyResolver, and registers it in the Application_Start method to be called at system startup.


//set dependency resolver 
var dependencyResolver = new NopDependencyResolver();
DependencyResolver.SetResolver(dependencyResolver);

8. Others

Event interception class: EventBroker: Filters requests sent to the system to prevent the system from crashing due to temporary errors or exceptions.

System startup tasks: IStartupTask, startup tasks are mainly the initialization and loading of the database.


Related articles: