• nopCommerce 3.9 大波浪系列 之 引擎 NopEngine


    本章涉及到的内容如下

    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接口,会获取所有”in”目录下*.dll 程序集,并通过反射可以获取到指定接口的实现类。

    3.获取所有IDependencyRegistrar接口实现类进行初始化,再调用 Register方法在IOC容器中注册类型及其实例,

    最重要的一个实现类就是“Nop.Web.FrameworkDependencyRegistrar.cs”,该实现类中将nop所需要的接口实现都注册到ioc容器中。

    我们在二次开发中可以创建IDependencyRegistrar的实现类添加自己的业务接口。如何注册大家学习下Autofac框架进一步了解。

    下图中列出了nop项目自带的一些IDependencyRegistrar方法。

    代码中也可以直接使用 EngineContext.Current.Resolve<“接口”>()进行调用,这种情况常用语视图中。

    image

    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在此也会自动进行配置的。

    image

    nop中只在Nop.Admin项目中使用AutoMapper进行对象映射。

    image

    而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中的配置不好理解可以留言一起讨论学习。


    本文地址:http://www.cnblogs.com/yaoshangjin/p/7221586.html 

    本文为大波浪原创、转载请注明出处。

    如果您认为这篇文章还不错或者有所收获,可以点击下方的【关注】按钮,因为你的支持是我继续写作,分享的最大动力!
    作者:大波浪
    声明: 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如果您发现博客中出现了错误,或者有更好的建议、想法,请及时与我联系!!如果想找我私下交流,可以私信或者加我QQ。
  • 相关阅读:
    学习使用&运算符
    企业发放的奖金根据利润提成。
    取一个整数a从右端开始的47位。
    jQuery Select操作大集合
    js 获取某年某月的最后一天
    sql 语句区分大小写查询
    js 冒泡排序
    一个初学者的程序自学计划
    JWNL体验
    (转)GIS相关的SCI、EI期刊
  • 原文地址:https://www.cnblogs.com/yaoshangjin/p/7221586.html
Copyright © 2020-2023  润新知