c#代码生成URL地址的示例
作者:超然 发布时间:2022-02-17 09:44:08
标签:c#,url,代码生成
目录
“头疼”
“吃药”
工具代码
使用代码
“头疼”
自己在用Angular做项目时,前端要请求后端数据时的代码如下
this.http.get("url/xxx")
这是请求一个URL地址数据最简单的代码,但是如此简单的代码还会遇到一些头疼的问题
URL地址拼写错误,有可能折腾半天才发现😑
后端修改了地址没通知到前端,测试不到位就炸了,不是所有项目都有那么规范的接口变更流程😑
查看代码的时候,看着URL地址,这个地址用途是哈?还要翻接口文档😑
“吃药”
为了解决这个问题,我们需要一个包含所有接口的文件
import { environment } from 'src/environments/environment';
export const WebAPI = {
/** 授权控制器 */
Auth: {
/** */
Controller: `${environment.host}/api/Auth`,
/** GET 获得用户 */
GetUser: `${environment.host}/api/Auth/GetUser`,
/** POST 登陆 */
Login: `${environment.host}/api/Auth/Login`,
},
}
那么请求代码就可以改成
this.http.get(WebAPI.Auth.GetUser)
但是维护这个文件是件吃力的事情,作为一个时刻想着如何偷懒的程序员,吃力的事情就让计算机去干,所以写一个代码生成工具。
工具代码
public static class BuildWebApiToTS
{
public static string Build(Assembly assembly, string prefix = "api/")
{
List<Controller> controllers = GetApis(assembly);
string code = CreateCode(controllers);
return code.ToString();
}
public static void BuildToFile(Assembly assembly, string path, string prefix = "api/")
{
var code = Build(assembly, prefix);
string existsCode = "";
if (System.IO.File.Exists(path) == true)
existsCode = System.IO.File.ReadAllText(path);
if (existsCode != code)
System.IO.File.WriteAllText(path, code);
}
#region 构造代码
public static string CreateCode(List<Controller> controllers, string prefix = "api/")
{
StringBuilder code = new StringBuilder();
code.AppendLine("import { environment } from 'src/environments/environment';");
code.AppendLine("export const WebAPI = {");
foreach (var coll in controllers.OrderBy(x => x.Name))
{
code.AppendLine($" /** {coll.ApiComments?.Title} */");
code.AppendLine($" {coll.Name}: {{");
code.AppendLine($" Controller: `${{environment.host}}/{prefix}{coll.Name}`,");
foreach (var action in coll.Actions.OrderBy(x => x.Name))
{
code.AppendLine($" /** {action.Type} {action.ApiComments?.Title} */");
code.AppendLine($" {action.Name}: `${{environment.host}}/{prefix}{coll.Name}/{action.Name}`,");
}
code.AppendLine($" }},");
}
code.AppendLine($"}};");
return code.ToString();
}
#endregion
#region 获得接口清单
public static List<Controller> GetApis(Assembly assembly)
{
List<Controller> controllers = new List<Controller>();
var collTypes = assembly.GetTypes().Where(x => x.GetCustomAttributes(typeof(ApiControllerAttribute), false).Count() > 0);
foreach (var collType in collTypes)
{
var controller = new Controller(collType.Name.Replace("Controller", ""));
controller.ApiComments = collType.GetCustomAttribute<ApiCommentsAttribute>();
controllers.Add(controller);
controller.Actions.AddRange(GetTypeMembers(collType, typeof(HttpGetAttribute), "GET"));
controller.Actions.AddRange(GetTypeMembers(collType, typeof(HttpPostAttribute), "POST"));
controller.Actions.AddRange(GetTypeMembers(collType, typeof(HttpPutAttribute), "PUT"));
controller.Actions.AddRange(GetTypeMembers(collType, typeof(HttpDeleteAttribute), "DELETE"));
}
return controllers;
}
private static List<Action> GetTypeMembers(Type type, Type whereType, string saveType)
{
var actonTypes = type.GetMembers().Where(x => x.GetCustomAttributes(whereType, false).Count() > 0);
List<Action> actons = new List<Action>();
foreach (var actonType in actonTypes)
{
var action = new Action(saveType, actonType.Name);
action.ApiComments = actonType.GetCustomAttribute<ApiCommentsAttribute>();
actons.Add(action);
}
return actons;
}
public record Controller(string Name)
{
public ApiCommentsAttribute ApiComments { get; set; }
public List<Action> Actions { get; set; } = new List<Action>();
}
public record Action(string Type, string Name)
{
public ApiCommentsAttribute ApiComments { get; set; }
}
#endregion
}
public class ApiCommentsAttribute : Attribute
{
public string Title { get; set; }
public ApiCommentsAttribute(string title)
{
Title = title;
}
}
使用代码
#if DEBUG
BuildWebApiToTS.BuildToFile(typeof(Program).Assembly, "ClientApp/src/app/web-api.ts");
#endif
上面代码大概的流程就是
利用反射读取程序集中包含
ApiControllerAttribute
特性的类利用发射读取
HttpGetAttribute
、HttpPostAttribute
、HttpPutAttribute
、HttpDeleteAttribute
特性的方法根据需要的格式生成代码
将代码文件写入
ClientApp/src/app/web-api.ts
有了这个东西带来以下好处
URL地址拼写错误问题,不存在的🎉
后端修改了接口,前端直接编译不过,立即发现问题🎉
鼠标停留,接口注释就显示了🎉
来源:https://www.cnblogs.com/TimChen44/archive/2021/04/10/14642328.html
0
投稿
猜你喜欢
- 1、异常分类通常分为三类:系统异常(SystemException),业务异常(BusinessException)和其他异常(Except
- ReentrantLock内部由Sync类实例实现。Sync类定义于ReentrantLock内部。Sync继承于AbstractQueue
- 本文实例为大家分享了flutter日期时间选择器的具体代码,供大家参考,具体内容如下1 日期选择器 //设置默认显示的日期为当前 DateT
- 前几天在跟公司大佬讨论一个问题时,看到他使用Handler的一种方式,旁边的同事在说:以前不是这么用的啊。这个问题引发了我的好奇,虽然当时翻
- 1、认识XML解析技术1.1、XML相关概念(1)DTD:XML语法规则,是XML文件的验证机制,可以通过比较XML文档和DTD文件看文档是
- 本文介绍WPF一种自定义按钮的方法。实现效果使用图片做按钮背景;自定义鼠标进入时效果;自定义按压效果;自定义禁用效果实现效果如下图所示:实现
- 本文介绍了Spring Security 控制授权的方法,分享给大家,具体如下:使用授权方法进行授权配置每一个 Spring Securit
- LocalDateTime 是 Java 8 中日期时间 API 提供的一个类,在日期和时间的表示上提供了更加丰富和灵活的支持。LocalD
- 前言:回顾之前的微信公众号配置和消息处理的内容,我们已经掌握了如何配置服务器与微信公众号建立连接,也掌握了通过消息管理的方式,对用户的信息进
- 前言假如有人问你这么几个问题,看能不能答上来Mybatis Mapper 接口没有实现类,怎么实现的 * JDK * 为什么不能对类进
- 这篇文章主要介绍了如何通过SpringBoot实现商城秒杀系统,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,
- 1.前言任何系统,我们不会傻傻的在每一个地方进行异常捕获和处理,整个系统一般我们会在一个的地方统一进行异常处理,spring boot全局异
- 1.概述MybatisPlus是国产的第三方插件, 它封装了许多常用的CURDapi,免去了我们写mapper.xml的重复劳动,这里介绍了
- 计算两点之间的距离然后在控制台输出,这个题目还是挺简单的。下面我们来看看具体代码。package com.swift;import java
- 需要的Maven<!--redis--> <dependency&g
- SpringCloudStream配置以下配置摘自《SpringCloud微服务实战》,配置主要包括两大部分:Stream配置(基础配置、通
- 在 Spring 容器中,两个 Bean 之间除了通过 <ref> 建立依赖关系外,还存在着一些特殊关系。1 继承在
- 一 技术发展技术的创新和发展都是为了解决一类问题二 框架设计Spring Framework 6大模块三 Spring AOP详解循环依赖问
- jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过
- 使用的场景常常遇到一些项目中多环境切换的问题。比如在开发过程中用到开发环境,在测试中使用测试环境,在生产中用生产环境的情况。springbo