• 通俗理解ABP中的模块Module


    🚀 优质资源分享 🚀

    学习路线指引(点击解锁)知识定位人群定位
    🧡 Python实战微信订餐小程序 🧡进阶级本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
    💛Python量化交易实战💛入门级手把手带你打造一个易扩展、更安全、效率更高的量化交易系统

    网上有不少文章说ABP的模块,有的直接翻译自官网介绍,有的分析Modlue的源代码,有的写一通代码,没什么注释,很少有能通俗说清的。那么,有两个问题:1.ABP中的模块到底是什么?2.搞这个东西是干嘛用的?难道是吃撑了没事做?下面我们来如何通俗回答这两个问题。

    第一个问题:ABP中的模块到底是什么?

    通俗的理解,这个东西就相当于程序集,你开发的项目不是有很多个类库吗?或者会有很多个所谓的“项目型”的程序集吗?如下图所示:

    里面不是有一堆东西吗?例如:AbpCompanyName.AbpProjectName.Application,AbpCompanyName.ProjectName.TestModule等等一堆东西,这些东西就是模块,也就是程序集。这并没有什么好稀奇,也没什么好神秘的,就是Assembly而已,只不过在ABP中,我们要让这个程序集成为一个Module模块,需要在这个程序集里单独定义一个继承于AbpModule的类,例如在我的AbpCompanyName.ProjectName.TestModule里,我就定义一个继承于AbpModule的AbpProjectNameTestModule类,并在它的 Initialize()方法里鼓捣一句注册的方法: IocManager.RegisterAssemblyByConvention(typeof(AbpProjectNameTestModule).Assembly)即可

    如下面代码所示:

     [DependsOn(typeof(AbpProjectName.AbpProjectNameApplicationModule))]
     public class AbpProjectNameTestModule:AbpModule
     {
    
    
     private string \_initStr = string.Empty;
    
     public string InitStr { get { return \_initStr; } set { \_initStr = value; }}
    
     public override void Initialize()
     {
     IocManager.RegisterAssemblyByConvention(typeof(AbpProjectNameTestModule).Assembly);
     //base.Initialize();
     }
    
    
     public AbpProjectNameTestModule()
     {
     //Init
                \_initStr = "AbpProjectNameTestModule() constructor init";
     Console.WriteLine(\_initStr);
     }
    
    
    
    
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    View Code
    请忽略其他几个次要的代码,只关注Initialize方法即可。

    第二个问题:搞这个东西是干嘛用的?

    既然这玩意就是程序集,那么还要费尽心思搞这个模块干嘛?岂不多此一举吗?难道让我吃饱了没事做吗?当然你可以不用,但用了有什么好处呢?如果我的项目有多个程序集,其中有一个依赖于其他几个程序集,如果这个项目一成不变倒没什么问题。但是如果有变,要替换其中依赖的一个或者几个程序集呢?那么问题就来了,凡是这个项目中有引用到的这些依赖程序集,都要一一替换,所以这个时候,就该使用ABP的模块了,它用来解决模块(或者叫程序集)的依赖问题

    ABP中使用模块依赖来解决这个问题,如果一个模块需要依赖于其他的模块,我们只需要在这个模块的上面写上属性DependsOn(XXXX模块)即可.例如我这里有一个叫做AbpProjectNameWebModule的模块,它依赖于AbpProjectNameApplicationModule,AbpProjectNameEntityFrameworkCoreModule,AbpAspNetCoreModule和AbpProjectNameTestModule,我们只需要在AbpProjectNameWebModule的头部加上这句即可:

    [DependsOn( typeof(AbpProjectNameApplicationModule), typeof(AbpProjectNameEntityFrameworkCoreModule), typeof(AbpAspNetCoreModule), typeof(AbpProjectNameTestModule) )]

    代码如下所示:

     [DependsOn(
     typeof(AbpProjectNameApplicationModule), 
     typeof(AbpProjectNameEntityFrameworkCoreModule), 
     typeof(AbpAspNetCoreModule),
     typeof(AbpProjectNameTestModule)
     )]
     public class AbpProjectNameWebModule : AbpModule
     {
     private readonly IConfigurationRoot \_appConfiguration;
    
     //构造函数注入 construc inject
            private AbpProjectNameApplicationModule \_appModule;
    
     private AbpProjectNameTestModule \_testModule;
    
     //Property inject
     //public AbpProjectNameApplicationModule \_appModule { get; set; }
    
    
    
            public AbpProjectNameWebModule(IWebHostEnvironment env)
     {
     \_appConfiguration = AppConfigurations.Get(env.ContentRootPath, env.EnvironmentName);
     //\_appModule.A();
     }
    
     public AbpProjectNameWebModule(AbpProjectNameApplicationModule appModule,AbpProjectNameTestModule testModule)
     {
     //构造函数注入
                \_appModule = appModule;
    
     \_testModule = testModule;
     }
    
    
    
     public override void PreInitialize()
     {
     Configuration.DefaultNameOrConnectionString = \_appConfiguration.GetConnectionString(AbpProjectNameConsts.ConnectionStringName);
    
     Configuration.Navigation.Providers.Add();
    
     Configuration.Modules.AbpAspNetCore()
     .CreateControllersForAppServices(
     typeof(AbpProjectNameApplicationModule).GetAssembly()
     );
    
     //test1
     \_appModule.A();
    
     //test2
     //string str = \_appModule.Bar();
    
     //test3
     //Baz baz = new Baz();
     }
    
     public override void Initialize()
     {
     IocManager.RegisterAssemblyByConvention(typeof(AbpProjectNameWebModule).GetAssembly());
     }
    
     public override void PostInitialize()
     {
     IocManager.Resolve()
     .AddApplicationPartsIfNotAddedBefore(typeof(AbpProjectNameWebModule).Assembly);
     }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    View Code
    其他东西先不要看,我们只看一句:

    public AbpProjectNameWebModule(AbpProjectNameApplicationModule appModule,AbpProjectNameTestModule testModule)
    {
    //构造函数注入
    \_appModule = appModule;
    
    \_testModule = testModule;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在AbpProjectNameWebModule构造函数中,我们居然可以不用手动实例化AbpProjectNameApplicationModule和AbpProjectNameTestModule,就可以直接获取到它们的实例了,是不是很神奇?当然是ABP框架在背后帮我们做了模块注入的事,具体可以看看AbpBootstrapper,AbpModuleManager,AbpModule等类的代码,重点关注模块管理类AbpModuleManager的RegisterModules方法,这个方法就是用来注入所有的模块,代码如下所示:

            /// 
            /// 将所有模块注册到IOC容器
     /// 
            /// 
            private void RegisterModules(ICollection moduleTypes)
     {
     foreach (var moduleType in moduleTypes)
     {
     \_iocManager.RegisterIfNot(moduleType);
     }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    至于模块是怎么加载的,怎样注册注入的,又是怎样初始化和运行的,需要仔细分析上面几个类的源代码,下篇再总结,上面涉及的代码也会以一个demo的形式发布出来。

  • 相关阅读:
    2022大厂高频面试题之HTML篇
    【Web】标准文档流
    MODBUS协议下,能否实现MCGS触摸屏与FX5U之间无线通讯?
    推荐一个专利检索的网站
    MDM现代设备管理解决方案如何保护企业设备安全,保证员工工作体验?
    Yii post()追加数据,模块之间的调用runAction
    SCI中讨论的注意事项
    Python循环控制
    电力感知边缘计算网关产品设计方案-电力采集
    【嵌入式】使用MultiButton开源库驱动按键并控制多级界面切换
  • 原文地址:https://blog.csdn.net/u013190417/article/details/126377184