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


猜你喜欢
- 我们已经写了一些Java程序。之前的每个Java程序都被保存为一个文件,比如Test.java。随后,该程序被编译为Test.class。我
- 前言目前互联网公司,大部分项目都是基于分布式,一个项目被拆分成几个小项目,这些小项目会分别部署在不同的计算机上面,这个叫做微服务。当一台计算
- 本文介绍了android视频截屏&手机录屏实现代码,分享给大家,希望对大家有帮助问题在android中有时候我们需要对屏幕进行截屏操
- 本文实例讲述了C#图形区域剪切的实现方法。分享给大家供大家参考。具体如下:using System;using System.Collect
- 一、概念和原理RPC(remote procedure call),远程过程调用,是客户端应用和服务端之间的会话。在客户端,它所需要的一些功
- 前言我们知道在Android开发中不能在非ui线程中更新ui,但是,有的时候我们需要在代码中执行一些诸如访问网络、查询数据库等耗时操作,为了
- Configuration configuration = ConfigurationManager.OpenExeConfiguratio
- 什么是tcpTcp通信有两个特点分别是面向连接,具有可靠性.面向连接:指的是客户端与服务端之间的连接,在通信之前会有三次握手的机制来确保连接
- 1、java.util.concurrent.atomic 的包里有AtomicBoolean, AtomicInteger,AtomicL
- 将一个字符串转化成String[]数组,提供两种方法前言将字符串转化成数组提供两种方法:1.split("");2.to
- 一:背景1. 讲故事每次项目预交付的时候,总会遇到各种奇葩的坑,我觉得有必要梳理一下以及如何快速解决的,让后来人避避坑,这篇就聊聊自己的所闻
- Android程序编码过程中,回调无处不在。从最常见的Activity生命周期回调开始,到BroadcastReceiver、Service
- 首先:因为工作需要,需要对接socket.io框架对接,所以目前只能使用netty-socketio。websocket是不支持对接sock
- 本文实例为大家分享了Android点击缩略图放大效果的具体代码,供大家参考,具体内容如下import android.animation.A
- 一、什么是状态模式定义:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。主要解决:当控制一个对象状态的条件表达式过于
- 前言什么是AptAPT从原理上讲是一个编译期的注解处理工具(Annotation Processing Tool)。一些主流的三方库(But
- 前言:对于一个程序员来说,尤其是在java web端开发的程序员,三大框架:Struts+Hibernate+Spring是必须要掌握熟透的
- 定义最短路问题的定义为:下图左侧是一幅带权有向图,以顶点 0 为起点到各个顶点的最短路径形成的最短路径树如下图右侧所示:带权有向图的实现在实
- 题目:使用struts2自定义 * ,完成用户登陆才能访问权限的实现在session中存放user变量表示用户登陆,若user为空则用户没有
- 简介本文用示例介绍使用MyBatis-Plus进行多表查询的方法,包括静态查询和动态查询。代码controllerpackage com.e