邵阳建网站多少钱网站制作的软件有哪些

web/2025/10/3 8:26:30/文章来源:
邵阳建网站多少钱,网站制作的软件有哪些,有没有做cad单的网站,企业数字化平台模块化和自动服务注册 基于 ASP.NET Core 开发的 Web 框架中#xff0c;最著名的是 ABP#xff0c;ABP 主要特点之一开发不同项目(程序集)时#xff0c;在每个项目中创建一个模块类#xff0c;程序加载每个程序集中#xff0c;扫描出所有的模块类#xff0c;然后通过模块…模块化和自动服务注册 基于 ASP.NET Core 开发的 Web 框架中最著名的是 ABPABP 主要特点之一开发不同项目(程序集)时在每个项目中创建一个模块类程序加载每个程序集中扫描出所有的模块类然后通过模块类作为入口初始化程序集。 使用模块化开发程序好处是不需要关注程序集如何加载配置。开发人员开发程序集时在模块类中配置如何初始化、如何读取配置使用者只需要将模块类引入进来即可由框架自动启动模块类。 Maomi.Core 也提供了模块化开发的能力同时还包括简单易用的自动服务注册。Maomi.Core 是一个很简洁的包可以在控制台、Web 项目、WPF 项目中使用在 WPF 项目中结合 MVVM 可以大量减少代码复杂度让代码更加清晰明朗。 快速入手 有 Demo1.Api、Demo1.Application 两个项目每个项目都有一个模块类模块类需要实现 IModule 接口。 Demo1.Application 项目的 ApplicationModule.cs 文件内容如下 public class ApplicationModule : IModule{// 模块类中可以使用依赖注入private readonly IConfiguration _configuration;public ApplicationModule(IConfiguration configuration){_configuration configuration;}public void ConfigureServices(ServiceContext services){// 这里可以编写模块初始化代码}} 如果要将服务注册到容器中在 class 上加上 [InjectOn] 特性即可。 public interface IMyService{int Sum(int a, int b);}[InjectOn] // 自动注册的标记public class MyService : IMyService{public int Sum(int a, int b){return a b;}} 上层模块 Demo1.Api 中的 ApiModule.cs 可以通过特性注解引用底层模块。 [InjectModuleApplicationModule]public class ApiModule : IModule{public void ConfigureServices(ServiceContext services){// 这里可以编写模块初始化代码}} 最后在程序启动时配置模块入口并进行初始化。 var builder WebApplication.CreateBuilder(args); builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen();// 注册模块化服务并设置 ApiModule 为入口 builder.Services.AddModuleApiModule();var app builder.Build(); 模块可以依赖注入 在 ASP.NET Core 配置 Host 时会自动注入一些框架依赖的服务如 IConfiguration 等因此在 .AddModuleApiModule() 开始初始化模块服务时模块获取已经注入的服务。 每个模块都需要实现 IModule 接口其定义如下 /// summary/// 模块接口/// /summarypublic interface IModule{/// summary/// 模块中的依赖注入/// /summary/// param namecontext模块服务上下文/paramvoid ConfigureServices(ServiceContext context);} 除了可以直接在模块构造函数注入服务之外还可以通过 ServiceContext context 获取服务和配置。 /// summary/// 模块上下文/// /summarypublic class ServiceContext{private readonly IServiceCollection _serviceCollection;private readonly IConfiguration _configuration;internal ServiceContext(IServiceCollection serviceCollection, IConfiguration configuration){_serviceCollection serviceCollection;_configuration configuration;}/// summary/// 依赖注入服务/// /summarypublic IServiceCollection Services _serviceCollection;/// summary/// 配置/// /summarypublic IConfiguration Configuration _configuration;} 模块化 因为模块之间会有依赖关系为了识别这些依赖关系Maomi.Core 使用树来表达依赖关系。 Maomi.Core 在启动模块服务时扫描所有模块类然后将模块依赖关系存放到模块树中然后按照左序遍历的算法对模块逐个初始化也就是先从底层模块开始进行初始化。 循环依赖检测 Maomi.Core 可以识别模块循环依赖 比如有以下模块和依赖 [InjectModuleA()] [InjectModuleB()] class C:IModule[InjectModuleA()] class B:IModule// 这里出现了循环依赖 [InjectModuleC()] class A:IModule// C 是入口模块 services.AddModuleC(); 因为 C 模块依赖 A、B 模块所以 A、B 是节点 C 的子节点而 A、B 的父节点则是 C。当把 A、B、C 三个模块以及依赖关系扫描完毕之后会得到以下的模块依赖树。 如下图所示每个模块都做了下标表示不同的依赖关系一个模块可以出现多次C1 - A0 表示 C 依赖 A。 C0 开始没有父节点则不存在循环依赖。 从 A0 开始A0 - C0 该链路中也没有出现重复的 A 模块。 从 C1 开始C1 - A0 - C0 该链路中 C 模块重复出现则说明出现了循环依赖。 从 C2 开始C2 - A1 - B0 - C0 该链路中 C 模块重复出现则说明出现了循环依赖。 模块初始化顺序 在生成模块树之后通过对模块树进行后序遍历即可。 比如有以下模块以及依赖。 [InjectModuleC()] [InjectModuleD()] class E:IModule[InjectModuleA()] [InjectModuleB()] class C:IModule[InjectModuleB()] class D:IModule[InjectModuleA()] class B:IModuleclass A:IModule// E 是入口模块 services.AddModuleE(); 生成模块依赖树如图所示 首先从 E0 开始扫描因为 E0 下存在子节点 C0、 D0那么就会先顺着 C0 再次扫描扫描到 A0 时因为 A0 下已经没有子节点了所以会对 A0 对应的模块 A 进行初始化。根据上图模块依赖树进行后序遍历初始化模块的顺序是已经被初始化的模块会跳过 服务自动注册 Maomi.Core 是通过 [InjectOn] 识别要注册该服务到容器中其定义如下 /// summary/// 依赖注入标记/// /summary[AttributeUsage(AttributeTargets.Class, AllowMultiple false, Inherited false)]public class InjectOnAttribute : Attribute{/// summary/// 要注入的服务/// /summarypublic Type[]? ServicesType { get; set; }/// summary/// 生命周期/// /summarypublic ServiceLifetime Lifetime { get; set; }/// summary/// 注入模式/// /summarypublic InjectScheme Scheme { get; set; }/// summary/// 是否注入自己/// /summarypublic bool Own { get; set; } false;/// summary/// /// /summary/// param namelifetime/param/// param namescheme/parampublic InjectOnAttribute(ServiceLifetime lifetime ServiceLifetime.Transient, InjectScheme scheme InjectScheme.OnlyInterfaces){Lifetime lifetime;Scheme scheme;}} 使用 [InjectOn] 时默认是注册服务为 Transient 生命周期且注册所有接口。 [InjectOn]public class MyService : IAService, IBService 等同于 services.AddTransientIAService, MyService(); services.AddTransientIBService, MyService();如果只想注册 IAService可以将注册模式设置为InjectScheme.Some 然后自定义注册的类型 [InjectOn(lifetime: ServiceLifetime.Transient,Scheme InjectScheme.Some,ServicesType new Type[] { typeof(IAService) })]public class MyService : IAService, IBService 也可以把自身注册到容器中 [InjectOn(Own true)] public class MyService : IMyService等同于 services.AddTransientIAService, MyService(); services.AddTransientMyService(); 如果服务继承了类、接口只想注册父类那么可以这样写 public class ParentService { }[InjectOn(Scheme InjectScheme.OnlyBaseClass)]public class MyService : ParentService, IDisposable 等同于 services.AddTransientParentService, MyService(); services.AddTransientMyService();如果只注册自身忽略接口等可以使用 [InjectOn(ServiceLifetime.Scoped, Scheme InjectScheme.None, Own true)] 模块化和自动服务注册的设计和实现 在本小节中我们将会开始设计一个支持模块化和自动服务注册的小框架从设计和实现 Maomi.Core 开始我们在后面的章节中会掌握更多框架技术的设计思路和实现方法从而掌握从零开始编写一个框架的能力。 项目说明 创建一个名为 Maomi.Core 的类库项目这个类库中将会包含框架核心抽象和实现代码。 为了减少命名空间长度便于开发的时候引入需要的命名空间打开 Maomi.Core.csproj 文件在 PropertyGroup 属性中添加一行配置 RootNamespaceMaomi/RootNamespace 配置 RootNamespace 属性之后我们在 Maomi.Core 项目中创建的类型其命名空间都会以 Maomi. 开头而不是 Maomi.Core。 接着为项目添加两个依赖包以便实现自动依赖注入和初始化模块时提供配置。 Microsoft.Extensions.DependencyInjection Microsoft.Extensions.Configuration.Abstractions 模块化设计 当本章的代码编写完毕之后我们可以这样实现一个模块、初始化模块、引入依赖模块。代码示例如下 [InjectModuleApplicationModule]public class ApiModule : IModule{private readonly IConfiguration _configuration;public ApiModule(IConfiguration configuration){_configuration configuration;}public void ConfigureServices(ServiceContext context){var configuration context.Configuration;context.Services.AddCors();}} 从这段代码笔者以从上到下的顺序来解读我们需要实现哪些技术点。 1模块依赖。 [InjectModuleApplicationModule] 表示当前模块需要依赖哪些模块。如果需要依赖多个模块可以使用多个特性示例如下 [InjectModuleDomainModule] [InjectModuleApplicationModule] 2模块接口和初始化。 每一个模块都需要实现 IModule 接口框架识别到类型继承了这个接口后才会把类型当作一个模块类进行处理。IModule 接口很简单只有 ConfigureServices(ServiceContext context) 一个方法可以在这个方法中编写初始化模块的代码。ConfigureServices 方法中有一个 ServiceContext 类型的参数 ServiceContext 中包含了 IServiceCollection、IConfiguration 模块可以从 ServiceContext 中获得当前容器的服务、启动时的配置等。 3依赖注入 每个模块的构造函数都可以使用依赖注入可以在模块类中注入需要的服务开发者可以在模块初始化时通过这些服务初始化模块。 基于以上三点我们可以先抽象出特性类、接口等由于这些类型不包含具体的逻辑因此从这一部分先下手实现起来会更简单可以避免大脑混乱编写框架时不知道要从哪里先下手。 创建一个 ServiceContext 类用于在模块间传递服务上下文信息其代码如下 public class ServiceContext{private readonly IServiceCollection _serviceCollection;private readonly IConfiguration _configuration;internal ServiceContext(IServiceCollection serviceCollection, IConfiguration configuration){_serviceCollection serviceCollection;_configuration configuration;}public IServiceCollection Services _serviceCollection;public IConfiguration Configuration _configuration;} 根据实际需求还可以在 ServiceContext 中添加日志等属性字段。 创建 IModule 接口。 public interface IModule{void ConfigureServices(ServiceContext services);} 创建 InjectModuleAttribute 特性用于引入依赖模块。 [AttributeUsage(AttributeTargets.Class, AllowMultiple true, Inherited false)]public class InjectModuleAttribute : Attribute{// 依赖的模块public Type ModuleType { get; private init; }public InjectModuleAttribute(Type type){ModuleType type;}}[AttributeUsage(AttributeTargets.Class, AllowMultiple true, Inherited false)]public sealed class InjectModuleAttributeTModule : InjectModuleAttributewhere TModule : IModule{public InjectModuleAttribute() : base(typeof(TModule)){}} 泛型特性属于 C# 11 的新语法。 定义两个特性类后我们可以使用 [InjectModule(typeof(AppModule))] 或 InjectModuleAppModule 的方式定义依赖模块。 自动服务注册的设计 当完成本章的代码编写后如果需要注入服务只需要标记 [InjectOn] 特性即可。 // 简单注册 [InjectOn] public class MyService : IMyService // 注注册并设置生命周期为 scope [InjectOn(ServiceLifetime.Scoped)] public class MyService : IMyService// 只注册接口不注册父类 [InjectOn(InjectScheme.OnlyInterfaces)] public class MyService : ParentService, IMyService 有时我们会有各种各样的需求例如 MyService 继承了父类 ParentService 和接口 IMyService但是只需要注册 ParentService而不需要注册接口又或者只需要注册 MyService而不需要注册 ParentService 、 IMyService。 创建 InjectScheme 枚举定义注册模式 public enum InjectScheme{// 注入父类、接口Any,// 手动选择要注入的服务Some,// 只注入父类OnlyBaseClass,// 只注入实现的接口OnlyInterfaces,// 此服务不会被注入到容器中None} 定义服务注册特性 // 依赖注入标记[AttributeUsage(AttributeTargets.Class, AllowMultiple false, Inherited false)]public class InjectOnAttribute : Attribute{// 要注入的服务public Type[]? ServicesType { get; set; }// 生命周期public ServiceLifetime Lifetime { get; set; }// 注入模式public InjectScheme Scheme { get; set; }// 是否注入自己public bool Own { get; set; } false;public InjectOnAttribute(ServiceLifetime lifetime ServiceLifetime.Transient, InjectScheme scheme InjectScheme.OnlyInterfaces){Lifetime lifetime;Scheme scheme;}} 模块依赖 因为模块之间会有依赖关系因此为了生成模块树需要定义一个 ModuleNode 类表示模块节点一个 ModuleNode 实例标识一个依赖关系。 /// summary/// 模块节点/// /summaryinternal class ModuleNode{// 当前模块类型public Type ModuleType { get; set; } null!;// 链表指向父模块节点用于循环引用检测public ModuleNode? ParentModule { get; set; }// 依赖的其它模块public HashSetModuleNode? Childs { get; set; }// 通过链表检测是否出现了循环依赖public bool ContainsTree(ModuleNode childModule){if (childModule.ModuleType ModuleType) return true;if (this.ParentModule null) return false;// 如果当前模块找不到记录则向上查找return this.ParentModule.ContainsTree(childModule);}public override int GetHashCode(){return ModuleType.GetHashCode();}public override bool Equals(object? obj){if (obj null) return false;if(obj is ModuleNode module){return GetHashCode() module.GetHashCode();}return false;}} 框架在扫描所有程序集之后通过 ModuleNode 实例将所有模块以及模块依赖组成一颗模块树通过模块树来判断是否出现了循环依赖。 比如有以下模块和依赖 [InjectModuleA()] [InjectModuleB()] class C:IModule[InjectModuleA()] class B:IModule// 这里出现了循环依赖 [InjectModuleC()] class A:IModule// C 是入口模块 services.AddModuleC(); 因为 C 模块依赖 A、B 模块所以 A、B 是节点 C 的子节点而 A、B 的父节点则是 C。 C.Childs new (){ A , B}A.ParentModule C B.ParentModule C 当把 A、B、C 三个模块以及依赖关系扫描完毕之后会得到以下的模块依赖树。一个节点即是一个 ModuleNode 实例一个模块被多次引入就会出现多次。 那么如果识别到循环依赖呢只需要调用 ModuleNode.ContainsTree()从一个 ModuleNode 实例中不断往上查找 ModuleNode.ParentModule 即可如果该链表中包含相同类型的模块即为循环依赖需要抛出异常。 比如从 C0 开始没有父节点则不存在循环依赖。 从 A0 开始A0 - C0 该链路中也没有出现重复的 A 模块。 从 C1 开始C1 - A0 - C0 该链路中 C 模块重复出现则说明出现了循环依赖。 所以是否出现了循环依赖判断起来是很简单的我们只需要从 ModuleNode.ContainsTree() 往上查找即可。 在生成模块树之后通过对模块树进行后序遍历即可。 比如有以下模块以及依赖。 [InjectModuleC()] [InjectModuleD()] class E:IModule[InjectModuleA()] [InjectModuleB()] class C:IModule[InjectModuleB()] class D:IModule[InjectModuleA()] class B:IModuleclass A:IModule// E 是入口模块 services.AddModuleE(); 伪代码示例如下 private static void InitModuleTree(ModuleNode moduleNode){if (moduleNode.Childs ! null){foreach (var item in moduleNode.Childs){InitModuleTree(item);}}// 如果该节点已经没有子节点// 如果模块没有处理过if (!moduleTypes.Contains(moduleNode.ModuleType)){InitInjectService(moduleNode.ModuleType);}} 未完待续...... 文章转载自痴者工良 原文链接https://www.cnblogs.com/whuanle/p/18227954 体验地址引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/86117.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

南京建设银行公积金查询网站培训行业网站建设是什么

贴个群号 WebGIS学习交流群461555818,欢迎大家 心路历程 当vue2由mapbox2升级为mapbox3的时候,您可能会遇到以下的问题 所有的代码都没有改变,升级为mapbox3就会出现部分矢量底图样式丢失,表现为图层已经成功加上,但…

网站的优势和劣势厦门正规的网站建设公司

一.为什么使用CSS 1.有效的传递页面信息 2.使用CSS美化过的页面文本,使页面漂亮、美观,吸引用户 3.可以很好的突出页面的主题内容,使用户第一眼可以看到页面主要内容 4.具有良好的用户体验 二.字体样式属性 1.font-family:英…

青岛网站建设市场北京网页制作教程

0 摘要 论文:A Systematic Study of Online Class Imbalance Learning With Concept Drift 发表:2018年发表在TNNLS上 源代码:? 作为一个新兴的研究课题,在线类非平衡学习往往结合了类非平衡和概念漂移的挑战。它处理…

怎么做找券网站智能家庭app下载

TRB(Transportation Research Board,美国交通研究委员会,简称TRB)会议是交通研究领域知名度最高学术会议之一,近年来的参会人数已经超过了2万名,是参与人数和国家最多的学术盛会。TRB会议几乎涵盖了交通领域…

购物网站开发教程 视频如何制作私人网站

有时候,产品思维和开发思维,由于出发点的不同,会产生较大的分歧。 作为一个开发,不仅要有自己的思维,也要了解产品的思维,这样才能在和产品的撕逼的战斗中所向披靡,百战百胜。 举个例子&#x…

网站建设中模板一般网站字体大小

一、虚拟机架构图 二、类加载过程 类加载器的作用:负责把class文件加载到内存中 类加载过程: 加载: 通过类的全限定名获取此类的二进制字节流文件的编码结构---->运行时的内存结构内存中生成一个class对象 链接: 验证&#x…

手机怎么制作网站教程视频教程网站建设空间空间有几种类型

目录 开发环境原理使用的QT库搭建开发环境准备word模板测试用例结果Gitee地址 开发环境 vs2022 Qt 5.9.1 msvc2017_x64,在文章最后提供了源码。 原理 Qt对于word文档的操作都是在书签位置进行插入文本、图片或表格的操作。 使用的QT库 除了基本的gui、core、…

搜索引擎有哪些网站江苏国泰做的网站案例

二叉树 打算先来了解二叉树基础,都是简单题,目的是熟悉代码格式和解题基础思路。 1、二叉树最大深度 二叉树最大深度 方法一、深度搜索 直接用原函数做递归,比较简单 /*** Definition for a binary tree node.* struct TreeNode {* …

好的网站2020北京网站建设 seo公司

4路电话光端机,采用桌面型机箱结构设计,提供来电显示功能的4路普通电话接口。那么,关于4路电话光端机的功能、应用及产品特性这一块你是否了解呢?接下来我们就跟随飞畅科技的小编一起来详细了解下吧! 4路电话光端机概…

校园网络设计宁波seo外包联系方式

Report QoR Suggestions report_qor_suggestions 命令是处理 QoR 建议对象时使用的主要命令。 QoR 建议对象会创建命令和属性来改善设计的时序性能( 欲知详情 , 请参阅 QoR 建议 ) 。 report_qor_suggestions 命令可执行两项任务 &am…

广州越秀区现在能去吗seo推广特点

一、前言最近一两个星期,加班,然后回去后弄自己的博客,把自己的电脑从 Windows 10 改到 Ubuntu 18.10 又弄回 Windows 10,原本计划的学习 Vue 中生命周期的相关知识目前也没有任何的进展,嗯,罪过罪过。看了…

有产品做推广 选哪个 网站做网站时的兼容问题

交换机故障一般可以分为硬件故障和软件故障两大类。硬件故障主要指交换机电源、背板、模块和端口等部件的故障,具体可以分为以下几类。接下来就由飞畅科技来为大家详细介绍下交换机的硬件故障问题,感兴趣的朋友就一起来看看吧! 一、电源故障…

原型样网站外贸网站定制建站

目录 1 疑问:Transformer的Decoder的输入输出都是什么 2 推理时Transformer的Decoder的输入输出 2.1 推理过程中的Decoder输入输出 2.2 整体右移一位 3 训练时Decoder的输入 参考文献: 1 疑问:Transformer的Decoder的输入输出都是什么 …

网站开发费入账重庆市建设工程信息网招标文件

贪婪加载顾名思议就是把所有要加载的东西一次性读取。 本节内容为了配合【延时加载】而诞生&#xff0c;贪婪加载和他本该在一起介绍&#xff0c;开发项目的过程中应该双管齐下&#xff0c;才能写出高质量的程序。 Dto 映射查询 Select<Tag>().Limit(10).ToList(a > n…

东莞seo网站管理深圳居家办公

目录 问题描述如果是bugbatch size的设置问题尝试使用GroupNorm解决batchsize不同带来的问题归一化的分类 参考文章 问题描述 深度学习网络训练时&#xff0c;使用较小的batch size训练网络后&#xff0c;如果换用较大的batch size进行evaluation&#xff0c;网络的预测能力会…

公司网站如何注册四川网站建设价格

首先说说为什么要写这个系列&#xff0c;大概有两点原因。这种文章阅读量确实高...对 IL 和 汇编代码 的学习巩固所以就决定写一下这个系列&#xff0c;如果大家能从中有所收获&#xff0c;那就更好啦&#xff01;一&#xff1a;params 应用层玩法 首先上一段 测试代码。class …

口碑好的高密网站建设怀仁网站建设

记录访问日志可以起到非常重要的作用&#xff0c;它不仅记录了API的使用情况&#xff0c;更可以反映API各种相关数据&#xff1b;通过分析日志可以得到API不同时间的负载情况&#xff0c;访问效率和流量分布&#xff0c;更进一步还能分析出用户的操作历史和行为这是非常有价值的…

j永久网站厦门建设局地址

http://www.boost.org/doc/libs/1_46_1/doc/html/string_algo.html 这个库是个 headers only library  这个库提供了STL没有提供的 string-related算法, 但是实现做到了可以用在任何 character 的 container上 split 在写在线状态的改造时候要把一个字符串中描述的几种类型拆…

泉州市网站建设重生北京上大学开网吧做网站的小说

1. 概述1.1 什么是Java语言Java语言&#xff1a;面向对象的程序设计语言与机器无关的二进制格式的类文件Java虚拟机(用来执行类文件)完整的软件程序包(跨平台的API和库)1.1.1 Java语言特点语法简单&#xff0c;功能强大分布式与安全性与平台无关解释、编译两种运行方式多线程动…

专业手机网站建设推荐下载2345浏览器并安装

和2.x不同的是&#xff0c;要用 action 来配置后端上传图片的接口地址&#xff1b; 再来一些配置项的命名有所不同&#xff0c;一般1.x的命名用 -&#xff0c;2.x的命名使用小驼峰&#xff1b; 1.x 的上传会自带删除时的提示框&#xff0c;2.x 没有&#xff1b; 重要的几个配置…