• ABP之模块系统


    简介

    ASP.NET Boilerplate提供了构建模块的基础结构,并将它们组合在一起以创建应用程序。 模块可以依赖于另一个模块。 通常,一个程序集被视为一个模块。 如果创建具有多个程序集的应用程序,建议您为每个程序集创建一个模块定义。

    模块系统目前专注于服务端,而不是客户端。

    模块定义

    定义一个派生自ABP包中的AbpModule的类作为一个模块。假设我们现在正在开发一个可以在不同应用程序中使用的Blog模块。最简单的模块定义如下:

    public class MyBlogApplicationModule : AbpModule
    {
        public override void Initialize()
        {
            IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
        }
    }

    如果需要,模块定义类负责通过依赖注入(DI)来注册它的类(它可以按常规方式完成,如上所示)。 它还可以配置应用程序和其他模块,为应用程序添加新功能等等......

    生命周期方法

    ABP在应用程序启动和关闭时调用某些特定的模块方法。我们可以覆盖这些方法去执行特定的任务。ABP按照依赖顺序来调用这些方法。如果模块A依赖于模块B,模块B就在模块A之前初始化。

    启动方法的正确顺序:PreInitialize-B,PreInitialize-A,Initialize-B,Initialize-A,PostInitialize-B和PostInitialize-A。 所有依赖图都是如此。 关闭方法也类似,但顺序相反。

    预初始化(PreInitialize)

    当应用程序启动时,首先调用此方法。它是在初始化之前配置框架和其他模块要执行的方法。

    我们也可以在这里编写一些特定的代码,然后在依赖注入注册之前执行。例如,如果是创建传统的注册类,则应使用IocManager.AddConventionalRegisterer方法在此处注册。

    初始化(Initialize)

    这是应该完成依赖注入注册的地方,它通常使用IocManager.RegisterAssemblyByConvention方法完成。也可以自定义依赖注入注册,到时请参阅依赖注入文档(后续写了会加链接)。

    初始化后(PostInitialize)

    此方法在启动过程中最后调用。 在这里解决依赖是安全的。

    关闭(Shutdown)

    应用程序关闭时调用此方法。

    模块依赖

    模块可以依赖于另一个模块。 我们需要使用DependsOn属性显式声明依赖项,如下所示:

    [DependsOn(typeof(MyBlogCoreModule))]
    public class MyBlogApplicationModule : AbpModule
    {
        public override void Initialize()
        {
            IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
        }
    }

    在这里,我们声明MyBlogApplicationModule依赖于MyBlogCoreModule,并且MyBlogCoreModule应在MyBlogApplicationModule之前初始化。

    ABP可以从启动模块开始递归地解析依赖关系并相应地初始化它们,启动模块初始化为最后一个模块。

    插件模块(PlugIn Modules)

    虽然从启动模块开始通过依赖项调查模块,但ANP也可以动态加载模块,AbpBootstrapper类定义了PlugInSources属性,该属性可用于添加资源以动态加载插件模块。插件源可以是实现IPlugInSource接口的任何类, PlugInFolderSource类实现从文件夹中的程序集获取插件模块。

    ASP.NET Core

    ABP ASP.NET Core在AddAbp扩展方法中定义选项,就是为了实现在Startup类中添加插件源。

    services.AddAbp<MyStartupModule>(options =>
    {
        options.PlugInSources.Add(new FolderPlugInSource(@"C:MyPlugIns"));
    });

    我们也可以调用AddFolder来实现最简单的语法。

    services.AddAbp<MyStartupModule>(options =>
    {
        options.PlugInSources.AddFolder(@"C:MyPlugIns");
    });

    ASP.NET MVC, Web API

    对于传统的ASP.NET MVC应用程序,我们可以通过覆盖global.asax中的Application_Start来添加插件文件夹,如下所示:

    public class MvcApplication : AbpWebApplication<MyStartupModule>
    {
        protected override void Application_Start(object sender, EventArgs e)
        {
            AbpBootstrapper.PlugInSources.AddFolder(@"C:MyPlugIns");
            //...
            base.Application_Start(sender, e);
        }
    }

    PlugIns中的控制器

    如果你的模块包含MVC或Web API控制器,则ASP.NET无法识别你的控制器。 要解决此问题,可以更改global.asax文件,如下所示:

    using System.Web;
    using Abp.PlugIns;
    using Abp.Web;
    using MyDemoApp.Web;
    
    [assembly: PreApplicationStartMethod(typeof(PreStarter), "Start")]
    
    namespace MyDemoApp.Web
    {
        public class MvcApplication : AbpWebApplication<MyStartupModule>
        {
        }
    
        public static class PreStarter
        {
            public static void Start()
            {
                //...
                MvcApplication.AbpBootstrapper.PlugInSources.AddFolder(@"C:MyPlugIns");
                MvcApplication.AbpBootstrapper.PlugInSources.AddToBuildManager();
            }
        }
    }

    附加组件

     IAssemblyFinder和ITypeFinder的默认实现(用于ABP识别应用程序中的特定类)仅时在这些程序集中查找模块程序集和类型。 我们可以覆盖模块中的GetAdditionalAssemblies方法来包含其他程序集。

    自定义模块

    模块中也可以有一些被其他依赖模块所使用的自定义方法。 假设MyModule2依赖于MyModule1并想要在PreInitialize方法中调用MyModule1的方法:

    public class MyModule1 : AbpModule
    {
        public override void Initialize()
        {
            IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
        }
    
        public void MyModuleMethod1()
        {
            //this is a custom method of this module
        }
    }
    
    [DependsOn(typeof(MyModule1))]
    public class MyModule2 : AbpModule
    {
        private readonly MyModule1 _myModule1;
    
        public MyModule2(MyModule1 myModule1)
        {
            _myModule1 = myModule1;
        }
    
        public override void PreInitialize()
        {
            _myModule1.MyModuleMethod1(); //Call MyModule1's method
        }
    
        public override void Initialize()
        {
            IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
        }
    }

    这里我们将构造函数注入MyModule1到MyModule2,因此MyModule2可以调用MyModule1的自定义方法。 仅当Module2依赖于Module1时才可以这样做。

    模块配置

    虽然可以使用自定义模块方法配置模块,但我们建议您使用启动配置系统来定义和设置模块的配置。

    模块声明周期
    模块类被自动注册为单例模式。

  • 相关阅读:
    将训练好的Tensorflow模型部署到web应用中
    python pip升级
    python time
    python 队列模拟递归遍历目录(广度遍历)
    python 栈模拟递归遍历目录(深度遍历)
    python 递归遍历目录
    python 队列
    python 栈
    python 递归
    python 语音模块
  • 原文地址:https://www.cnblogs.com/yixuanhan/p/9485244.html
Copyright © 2020-2023  润新知