1. 程式人生 > >nopCommerce 3.9 大波浪系列 之 引擎 NopEngine

nopCommerce 3.9 大波浪系列 之 引擎 NopEngine

provide float 框架 blog exp splay activator 註入 title

本章涉及到的內容如下

1.EngineContext初始化IEngine實例

2.Autofac依賴註入初始化

3.AutoMapper框架初始化

4.啟動任務初始化

一.EngineContext初始化

nopCommerce應用啟動時首先調用EngineContext.Initialize(false) 進行初始化引擎,

並對IEngine接口進行初始化。IEngine用於實現依賴註入和初始化工作。nop中使用Autofac進行依賴註入。

你會發現nop中很多如:EngineContext.Current.Resolve<ICacheManager>();這樣的語句,該Resolve方法用於返回對應接口的實例。

技術分享
  1  [MethodImpl(MethodImplOptions.Synchronized)]//可以確保在不同線程中運行的該方式以同步的方式運行
  2         public static IEngine Initialize(bool forceRecreate)
  3         {
  4             if (Singleton<IEngine>.Instance == null || forceRecreate)
  5             {
  6                 Singleton<IEngine>.Instance = new
NopEngine(); 7 8 var config = ConfigurationManager.GetSection("NopConfig") as NopConfig; 9 Singleton<IEngine>.Instance.Initialize(config); 10 } 11 return Singleton<IEngine>.Instance; 12 }
EngineContext.Initialize(false)

二.IEngine接口初始化

NopEngine實現IEngine接口,並在Initialize(NopConfig config)方法中對應用進行初始化工作。

同時使用Resolve方法返回對應接口實例。

首先我們看下Initialize(NopConfig config)方法都做了什麽。

  1   public void Initialize(NopConfig config)
  2         {
  3             //register dependencies 註冊依賴項 nop 使用 Autofac進行依賴註入
  4             RegisterDependencies(config);
  5 
  6             //register mapper configurations 註冊對象映射配置 nop 使用 AutoMapper進行對象映射
  7             RegisterMapperConfiguration(config);
  8 
  9             //startup tasks 啟動任務
 10             if (!config.IgnoreStartupTasks)
 11             {
 12                 RunStartupTasks();
 13             }
 14 
 15         }

1.調用RegisterDependencies(config)方法進行依賴註入(IOC)初始化工作

我們先看看代碼

  1     /// <summary>
  2         /// 使用AutoFac註冊依賴項 
  3         /// 遍歷所有的實現IDependencyRegistrar接口實例進行註冊
  4         /// Register dependencies
  5         /// </summary>
  6         /// <param name="config">Config</param>
  7         protected virtual void RegisterDependencies(NopConfig config)
  8         {
  9             var builder = new ContainerBuilder();
 10 
 11             //dependencies
 12             var typeFinder = new WebAppTypeFinder();
 13             builder.RegisterInstance(config).As<NopConfig>().SingleInstance();
 14             builder.RegisterInstance(this).As<IEngine>().SingleInstance();
 15             builder.RegisterInstance(typeFinder).As<ITypeFinder>().SingleInstance();
 16 
 17             //register dependencies provided by other assemblies
 18             var drTypes = typeFinder.FindClassesOfType<IDependencyRegistrar>();
 19             var drInstances = new List<IDependencyRegistrar>();
 20             foreach (var drType in drTypes)
 21                 drInstances.Add((IDependencyRegistrar) Activator.CreateInstance(drType));
 22             //sort
 23             drInstances = drInstances.AsQueryable().OrderBy(t => t.Order).ToList();
 24             foreach (var dependencyRegistrar in drInstances)
 25                 dependencyRegistrar.Register(builder, typeFinder, config);
 26 
 27             var container = builder.Build();
 28             this._containerManager = new ContainerManager(container);
 29 
 30             //set dependency resolver
 31             DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
 32         }

1.默認使用Autofac依賴註入框架,因此首先創建ioc容器 var builder = new ContainerBuilder();

2.容器中註冊NopConfig,IEngine,ITypeFinder。

這裏重點說下ITypeFinder接口,該接用於返回程序集,獲取某個接口所有實現類。該接口被廣泛用在 Nop Engine中。

WebAppTypeFinder類實現了ITypeFinder接口,會獲取所有”\bin”目錄下*.dll 程序集,並通過反射可以獲取到指定接口的實現類。

3.獲取所有IDependencyRegistrar接口實現類進行初始化,再調用 Register方法在IOC容器中註冊類型及其實例,

最重要的一個實現類就是“Nop.Web.Framework\DependencyRegistrar.cs”,該實現類中將nop所需要的接口實現都註冊到ioc容器中。

我們在二次開發中可以創建IDependencyRegistrar的實現類添加自己的業務接口。如何註冊大家學習下Autofac框架進一步了解。

下圖中列出了nop項目自帶的一些IDependencyRegistrar方法。

代碼中也可以直接使用 EngineContext.Current.Resolve<“接口”>()進行調用,這種情況常用語視圖中。

技術分享

2.調用RegisterMapperConfiguration(config)方法進行對象映射

還是先看代碼

  1 /// <summary>
  2         /// AutoMapper為對象映射
  3         /// 遍歷所有的實現IMapperConfiguration接口實例進行註冊
  4         /// Register mapping
  5         /// </summary>
  6         /// <param name="config">Config</param>
  7         protected virtual void RegisterMapperConfiguration(NopConfig config)
  8         {
  9             //dependencies
 10             var typeFinder = new WebAppTypeFinder();
 11 
 12             //register mapper configurations provided by other assemblies
 13             var mcTypes = typeFinder.FindClassesOfType<IMapperConfiguration>();
 14             var mcInstances = new List<IMapperConfiguration>();
 15             foreach (var mcType in mcTypes)
 16                 mcInstances.Add((IMapperConfiguration)Activator.CreateInstance(mcType));
 17             //sort
 18             mcInstances = mcInstances.AsQueryable().OrderBy(t => t.Order).ToList();
 19             //get configurations
 20             var configurationActions = new List<Action<IMapperConfigurationExpression>>();
 21             foreach (var mc in mcInstances)
 22                 configurationActions.Add(mc.GetConfiguration());
 23             //register
 24             AutoMapperConfiguration.Init(configurationActions);
 25         }

使用AutoMapper框架進行對象映射,簡單些就是Dto與Model之間的轉換.

這裏同樣使用ITypeFinder 獲取所有IMapperConfiguration的實現類,並在實現類中完成Dto與Model之間的映射關系。

同樣如果自行擴展IMapperConfiguration的實現類,nop在此也會自動進行配置的。

技術分享

nop中只在Nop.Admin項目中使用AutoMapper進行對象映射。

技術分享

而Nop.Web項目並沒有使用AutoMapper而是用擴展來實現的。

3.運行啟動任務

最後說下應用啟動時運行啟動任務

在配置類NopConfig中IgnoreStartupTasks來控制是否啟動

  1  /// <summary>
  2         /// 啟動時運行的任務任務
  3         /// 遍歷所有實現IStartupTask接口的實例
  4         /// Run startup tasks
  5         /// </summary>
  6         protected virtual void RunStartupTasks()
  7         {
  8             var typeFinder = _containerManager.Resolve<ITypeFinder>();
  9             var startUpTaskTypes = typeFinder.FindClassesOfType<IStartupTask>();
 10             var startUpTasks = new List<IStartupTask>();
 11             foreach (var startUpTaskType in startUpTaskTypes)
 12                 startUpTasks.Add((IStartupTask)Activator.CreateInstance(startUpTaskType));
 13             //sort
 14             startUpTasks = startUpTasks.AsQueryable().OrderBy(st => st.Order).ToList();
 15             foreach (var startUpTask in startUpTasks)
 16                 startUpTask.Execute();
 17         }

同樣使用ITypeFinder 來獲取所有 IStartupTask接口的實現類,並調用Execute()方法來執行。

三.總結:

NopEngine實現nop引擎,並通過Autofac,AutoMapper對nop進行初始化。

ITypeFinder 接口很重要,因為nop擴展功能都依賴於它來實現。nop有很好的接口截止,大家進行二次開發的時候進行接口實現就可以了,nop會自動進行初始化配置。

如果Autofac,AutoMapper中的配置不好理解可以留言一起討論學習。

nopCommerce 3.9 大波浪系列 之 引擎 NopEngine