当前位置: 首页 > news >正文

网站维护主要是做哪些常州溧阳市建设局网站

网站维护主要是做哪些,常州溧阳市建设局网站,自己设计logo怎么做,有谁帮做网站的一、简要说明本篇文章主要分析 Abp vNext 当中的模块系统#xff0c;从类型构造层面上来看#xff0c;Abp vNext 当中不再只是单纯的通过 AbpModuleManager 来管理其他的模块#xff0c;它现在则是 IModuleManager 和 IModuleLoader 来协同工作#xff0c;其他的代码逻辑并… 一、简要说明本篇文章主要分析 Abp vNext 当中的模块系统从类型构造层面上来看Abp vNext 当中不再只是单纯的通过 AbpModuleManager 来管理其他的模块它现在则是 IModuleManager 和 IModuleLoader 来协同工作其他的代码逻辑并无太大变化。Abp vNext 规定每个模块必须继承自 IAbpModule 接口这样 vNext 系统在启动的时候才会扫描到相应的模块。与原来 Abp 框架一样每个模块可以通过 DependsOnAttribute 特性来确定依赖关系算法还是使用拓扑排序算法来根据依赖性确定模块的加载顺序。(从最顶层的模块依次加载直到启动模块。)以我们的 Demo 项目为例这里通过拓扑排序之后的依赖关系如上图这样最开始执行的即 AbpDataModule 模块然后再是 AbpAuditingModule 以此类推直到我们的启动模块 DemoAppModule。在 Abp vNext 当中所有的组件库/第三方库都是以模块的形式呈现的模块负责管理整个库的生命周期包括注册组件配置组件销毁组件等。在最开始的 Abp 框架当中一个模块有 4 个生命周期它们都是在抽象基类 AbpModule 当中定义的分别是 预加载、初始化、初始化完成、销毁。前三个生命周期是依次执行的 预加载-初始化-初始化完成而最后一个销毁动作则是在程序终止的时候通过 AbpModuleManager 遍历模块调用其 ShutDown() 方法进行销毁动作。新的 Abp vNext 框架除了原有的四个生命周期以外还抽象出了 IOnPreApplicationInitialization、IOnApplicationInitialization、IOnPostApplicationInitialization、IOnApplicationShutdown。从名字就可以看出来新的四个生命周期是基于应用程序级别的而不是模块级别。这是什么意思呢在 Abp vNext 框架当中模块按照功能用途划分为两种类型的模块。第一种是 框架模块它是框架的核心模块比如缓存、EF Core 等基础设施就属于框架模块其模块的逻辑与处理基本都在传统的三个生命周期进行处理。在我们的 services.AddApplication 阶段就已经完成所有初始化可以给 应用程序模块 提供服务。第二种则是 应用程序模块这种模块则是实现了特定的业务/功能例如身份管理、租户管理等而新增加的四个生命周期基本是为这种类型的模块服务的。在代码和结构上来说两者并没有区别在这里仅仅是按用途进行了一次分类。单就模块系统来说其基本的作用就类似于一个配置类配置某种组件的各种参数和一些默认逻辑。二、源码分析2.1 模块系统的基础设施模块的初始化动作是在 AbpApplicationBase 基类开始的在该基类当中除了注入模块相关的基础设施以外。还定义了模块的初始化方法即 LoadModules() 方法在该方法内部是调用的 IModuleLoader 去执行具体的加载操作。internal AbpApplicationBase( [NotNull] Type startupModuleType, [NotNull] IServiceCollection services, [CanBeNull] ActionAbpApplicationCreationOptions optionsAction){ Check.NotNull(startupModuleType, nameof(startupModuleType)); Check.NotNull(services, nameof(services)); StartupModuleType startupModuleType; Services services; services.TryAddObjectAccessorIServiceProvider();var options new AbpApplicationCreationOptions(services); optionsAction?.Invoke(options); services.AddSingletonIAbpApplication(this); services.AddSingletonIModuleContainer(this); services.AddCoreServices(); services.AddCoreAbpServices(this, options); Modules LoadModules(services, options);}private IReadOnlyListIAbpModuleDescriptor LoadModules(IServiceCollection services, AbpApplicationCreationOptions options){return services .GetSingletonInstanceIModuleLoader() .LoadModules( services, StartupModuleType, options.PlugInSources );}2.2 模块的初始化进入 IModuleLoader 的默认实现 ModuleLoader在它的 LoadModules() 方法中基本逻辑如下扫描当前应用程序的所有模块类并构建模块描述对象。基于模块描述对象使用拓扑排序算法来按照模块的依赖性进行排序。排序完成之后遍历排序完成的模块描述对象依次执行它们的三个生命周期方法。public IAbpModuleDescriptor[] LoadModules( IServiceCollection services, Type startupModuleType, PlugInSourceList plugInSources){ Check.NotNull(services, nameof(services)); Check.NotNull(startupModuleType, nameof(startupModuleType)); Check.NotNull(plugInSources, nameof(plugInSources));var modules GetDescriptors(services, startupModuleType, plugInSources); modules SortByDependency(modules, startupModuleType); ConfigureServices(modules, services);return modules.ToArray();}在搜索模块类型的时候是使用的 AbpModuleHelper 工具类提供的 .FindAllModuleTypes() 方法。该方法会将我们的启动模块传入根据模块上面的 DependsOn() 标签递归构建 模块描述对象 的集合。private ListIAbpModuleDescriptor GetDescriptors( IServiceCollection services, Type startupModuleType, PlugInSourceList plugInSources){var modules new ListAbpModuleDescriptor(); FillModules(modules, services, startupModuleType, plugInSources); SetDependencies(modules);return modules.CastIAbpModuleDescriptor().ToList();}protected virtual void FillModules( ListAbpModuleDescriptor modules, IServiceCollection services, Type startupModuleType, PlugInSourceList plugInSources){foreach (var moduleType in AbpModuleHelper.FindAllModuleTypes(startupModuleType)) { modules.Add(CreateModuleDescriptor(services, moduleType)); }}走进 AbpModuleHelper 静态类其代码与结构与原有的 Abp 框架类似首先看下它的 FindAllModuleTypes() 方法根据启动模块的类型递归查找所有的模块类型并添加到一个集合当中。public static ListType FindAllModuleTypes(Type startupModuleType){var moduleTypes new ListType(); AddModuleAndDependenciesResursively(moduleTypes, startupModuleType);return moduleTypes;}private static void AddModuleAndDependenciesResursively(ListType moduleTypes, Type moduleType){ AbpModule.CheckAbpModuleType(moduleType);if (moduleTypes.Contains(moduleType)) {return; } moduleTypes.Add(moduleType);foreach (var dependedModuleType in FindDependedModuleTypes(moduleType)){ AddModuleAndDependenciesResursively(moduleTypes, dependedModuleType); }}public static ListType FindDependedModuleTypes(Type moduleType){ AbpModule.CheckAbpModuleType(moduleType);var dependencies new ListType();var dependencyDescriptors moduleType .GetCustomAttributes() .OfTypeIDependedTypesProvider();foreach (var descriptor in dependencyDescriptors) {foreach (var dependedModuleType in descriptor.GetDependedTypes()) { dependencies.AddIfNotContains(dependedModuleType); } }return dependencies;}以上操作完成之后我们就能获得一个平级的模块描述对象集合我们如果要使用拓扑排序来重新针对这个集合进行排序就需要知道每个模块的依赖项根据 IAbpModuleDescriptor 的定义我们可以看到它有一个 Dependencies 集合来存储它的依赖项。public interface IAbpModuleDescriptor{ Type Type { get; } Assembly Assembly { get; } IAbpModule Instance { get; }bool IsLoadedAsPlugIn { get; } IReadOnlyListIAbpModuleDescriptor Dependencies { get; }}而 SetDependencies(ListAbpModuleDescriptor modules) 方法就是来设置每个模块的依赖项的代码逻辑很简单。遍历之前的平级模块描述对象集合根据当前模块的类型定义找到其依赖项的类型定义。根据这个类型定义去平级的模块描述对象集合搜索将搜索到的结果存储到当前的模块描述对象中的 Dependencies 属性当中。protected virtual void SetDependencies(ListAbpModuleDescriptor modules){foreach (var module in modules) { SetDependencies(modules, module); }}protected virtual void SetDependencies(ListAbpModuleDescriptor modules, AbpModuleDescriptor module){foreach (var dependedModuleType in AbpModuleHelper.FindDependedModuleTypes(module.Type)) {var dependedModule modules.FirstOrDefault(m m.Type dependedModuleType);if (dependedModule null) {throw new AbpException(Could not find a depended module dependedModuleType.AssemblyQualifiedName for module.Type.AssemblyQualifiedName); } module.AddDependency(dependedModule); }}最后的拓扑排序就不在赘述关于拓扑排序的算法可以在我的 这篇 博文当中找到。关于模块的最后操作就是执行模块的三个生命周期方法了这块代码在 ConfigureServices() 方法当中没什么特别的的处理遍历整个模块描述对象集合依次执行几个方法就完了。只是在这里的生命周期方法与之前的不一样了这里会为每个方法传入一个服务上下文对象主要是可以通过 IServiceCollection 来配置各个模块的参数而不是原来的 Configuration 属性。protected virtual void ConfigureServices(ListIAbpModuleDescriptor modules, IServiceCollection services){var context new ServiceConfigurationContext(services); services.AddSingleton(context);foreach (var module in modules) {if (module.Instance is AbpModule abpModule) { abpModule.ServiceConfigurationContext context; } }foreach (var module in modules.Where(m m.Instance is IPreConfigureServices)) { ((IPreConfigureServices)module.Instance).PreConfigureServices(context); }foreach (var module in modules) {if (module.Instance is AbpModule abpModule) {if (!abpModule.SkipAutoServiceRegistration) { services.AddAssembly(module.Type.Assembly); } } module.Instance.ConfigureServices(context); }foreach (var module in modules.Where(m m.Instance is IPostConfigureServices)) { ((IPostConfigureServices)module.Instance).PostConfigureServices(context); }foreach (var module in modules) {if (module.Instance is AbpModule abpModule) { abpModule.ServiceConfigurationContext null; } }}以上动作都是在 Startup 类当中的 ConfigureService() 方法中执行你可能会奇怪剩下的四个应用程序生命周期的方法在哪儿执行的呢这几个方法是被抽象成了 IModuleLifecycleContributor 类型在前面的 AddCoreAbpService()方法的内部就被添加到了配置项里面。internal static void AddCoreAbpServices(this IServiceCollection services, IAbpApplication abpApplication, AbpApplicationCreationOptions applicationCreationOptions){ services.ConfigureModuleLifecycleOptions(options { options.Contributors.AddOnPreApplicationInitializationModuleLifecycleContributor(); options.Contributors.AddOnApplicationInitializationModuleLifecycleContributor(); options.Contributors.AddOnPostApplicationInitializationModuleLifecycleContributor(); options.Contributors.AddOnApplicationShutdownModuleLifecycleContributor(); });}执行的话则是在 Startup 类的 Configure() 方法当中它会调用 AbpApplicationBase 基类的 InitializeModules() 方法在该方法内部也是遍历所有的 Contributor (生命周期)再将所有的模块对应的方法调用一次而已。public void InitializeModules(ApplicationInitializationContext context){ LogListOfModules();foreach (var Contributor in _lifecycleContributors) {foreach (var module in _moduleContainer.Modules) { Contributor.Initialize(context, module.Instance); } } _logger.LogInformation(Initialized all modules.);}这里操作可能有点看不懂不是说调用模块的生命周期方法么为啥还将实例传递给 Contributor 呢我们找到一个 Contributor 的定义就知道了。public class OnApplicationInitializationModuleLifecycleContributor : ModuleLifecycleContributorBase{public override void Initialize(ApplicationInitializationContext context, IAbpModule module){ (module as IOnApplicationInitialization)?.OnApplicationInitialization(context); }}这里我认为 Abp vNext 把 Contributor 抽象出来可能是为了后面方便扩展吧如果你也有自己的看法不妨在评论区留言。三、总结至此整个模块系统的解析就结束了如果看过 Abp 框架源码解析的朋友就可以很明显的感觉到新框架的模块系统除了生命周期多了几个以外其他的变化很少基本没太大的变化。在 Abp vNext 框架里面模块系统是整个框架的基石了解了模块系统以后对于剩下的设计就很好理解了。原文地址https://www.cnblogs.com/myzony/p/10734357.html.NET社区新闻深度好文欢迎访问公众号文章汇总 http://www.csharpkit.com
http://www.zqtcl.cn/news/362431/

相关文章:

  • 摄影师个人网站模板宝坻集团网站建设
  • 比较多人用什么网站做推广wordpress数据库表管理系统
  • 网页开发和游戏开发东莞优化怎么做seo
  • 北京网站搭建开发高级网页设计教程
  • 北京南站是中高风险地区吗网站建设上机实验心得
  • 大学生做兼职的网站有哪些免费行情软件网站有哪些
  • 静安手机网站建设常见的网络营销方法及其效果
  • 怎么改版网站湖南长沙地图
  • 中卫网站推广公司如何自创app软件
  • 无棣网站建设电子商务网站设计原理书籍
  • 做t-shirt素材网站企业网站建设结论
  • 唐山公司做网站查询建筑资质的网站
  • 邯郸的网站建设网站正能量入口
  • 网站导航栏最多可以做几个宝安网站设计排名
  • 自己怎样用手机建网站网件app
  • 周口网站开发西安市建设厅网站
  • 怎么授权小说做游戏网站论坛网站开发语言
  • 烟台商城网站建设怎么样引流顾客到店方法
  • 北京做网站公司的排名python基础教程pdf
  • 网站建设为什么学flash建设工程询价网站有哪些
  • 网站内容建设机制企业管理模式有哪些
  • 中山网站建设文化价格建网站域名注册
  • 手机电影网站怎么做大连最新发布
  • 珠三角网站建设网页制作专业知识
  • 罗湖微信网站制作深圳做网站哪个公司最好
  • ps如何做ppt模板下载网站网站模板分类
  • 网站建设在线网站服务器和直播服务器一样吗
  • iapp网站做软件教程朋友圈广告投放平台
  • 优门设 网站网站代理 正规备案
  • 衡水做wap网站上海做网站吧