前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >abp架构详解_大数定律通俗理解

abp架构详解_大数定律通俗理解

作者头像
全栈程序员站长
发布2022-09-23 19:24:37
3560
发布2022-09-23 19:24:37
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

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

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

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

abp架构详解_大数定律通俗理解
abp架构详解_大数定律通俗理解

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

如下面代码所示:

代码语言:javascript
复制
 [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);
        }




    }

View Code

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

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

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

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

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

代码如下所示:

代码语言:javascript
复制
 [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<AbpProjectNameNavigationProvider>(); 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<ApplicationPartManager>() .AddApplicationPartsIfNotAddedBefore(typeof(AbpProjectNameWebModule).Assembly); } }

View Code

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

代码语言:javascript
复制
public AbpProjectNameWebModule(AbpProjectNameApplicationModule appModule,AbpProjectNameTestModule testModule) { //构造函数注入 _appModule = appModule; _testModule = testModule; }

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

代码语言:javascript
复制
 /// <summary> /// 将所有模块注册到IOC容器 /// </summary> /// <param name="moduleTypes"></param> private void RegisterModules(ICollection<Type> moduleTypes) { foreach (var moduleType in moduleTypes) { _iocManager.RegisterIfNot(moduleType); } }

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

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/170753.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档