.NET开发规范
2021-07-09 09:04
标签:防止 序列化 渠道 站点 存在 gem asc 指定 链接服务器 一、命名规则 (1) Pascal命名法:将标识符的首字母和后面连接的每个单词的首字母都大写。 例如:BackColor (2) Camel命名法:标识符的首字母小写,而每个后面连接的单词的首字母都大写。 例如:backColor (3) 变量、类名、成员变量、方法等命名,禁止采用:英文和拼音组合、拼音命名、非规范的英文简写命名、汉字命名(特殊情况除外:如部分枚举采用汉字); 说明:名字定义不怕长,力求准确,并且可读性友好; 反例:decimal jiage = 0M;//价格 (1) C#方法参数、内部变量命名:应采用Camel命名法,即,首字母小写; 正例:int userId = 0; (2) C#类内成员属性:应采用Pascal命名法,即,首字母大写; 正例:public int UserId { get; set; } (3) C#枚举(enum)命名:应采用Pascal命名法,即,首字母大写; 说明:应该为英文单词的名词单数形式,不应该增加 Enum前缀或者后缀;根据实际业务定义即可; 正例:UserType 反例:UserTypeEnum|UserTypes (4) C#接口(interface)命名:应采用Pascal命名法,即,首字母大写; 说明:应该统一以I字母开头,实现类则去掉对应的I字母; (5) C#实体对象(Model)命名:采用Pascal命名法,即,首字母大写; 说明: 数据库表实体应命名为ModelInfo,Model为数据库表名; 数据模型(DataModel)应该定义为DModelInfo,D为前缀,Info为后缀,Model为相关业务名称; 视图模型(ViewModel)应该定义为VModelInfo,V为前缀,Info为后缀,Model为页面或相关业务名称; 正例:TUserInfo|DUserLogInfo|VUserListInfo (6) C#数据层(DAL)类命名:应采用Pascal命名法,即,首字母大写; 说明:应统一采用DAL后缀,ModelDAL,Model为实体名称(去掉Info后缀); 正例:TUserDAL (7) C#持久层(Persistence,iBatisNet)命名:map文件名一般保持和文件内的namespace一致,并且和数据库实体表名一致;方法名一般和DAL层的调用方法保持一致,方便阅读; (8) C#业务层(BLL)类命名:应采用Pascal命名法,即,首字母大写; 说明:应统一采用BLL后缀,ModelBLL,Model为实体名称(去掉Info后缀); 正例:TUserBLL|DUserLogBLL (9) 对象类型成员的命名规则:满足类内成员属性的规则; 说明:应当以完整的类名去掉前缀和后缀之后的实体名作为属性名; 正例:public staticTUserInfo TUser { get; set; } 反例:public staticTUserInfo TUserInfo{ get; set; } (10) 常量命名规范:全部字母大写,每个单词用下划线分割; 正例:/// private const int CHANNEL_ID= 175; (11) js变量和方法名规则:均应该采用Camel命名法,首字母小写; (12) 数据库对象和字段的命名尽量采用Pascal命名法,即,首字母大写; 说明:常见数据库对象的命名除符合命名规范之外,应尽量使用前缀来区分对象的类型。 正例:表:TUser|视图:VUserLevel|自定义函数:GetMaxId()|存储过程:ProcSetUserState (13) WCF引用的服务命名规范,建议引用的命名空间添加WCFService前缀; (1) 文件名遵从Pascal命名法,无特殊情况,扩展名小写; (2) 使用统一而又通用的文件扩展名:C# 类 .cs ; 正例:TUserInfo.cs 为了方便阅读,单行代码应尽量控制在一屏之内,否则应按照实际情况调整换行显示: (1) 在代码或者表达式的逗号之后换行; (2) 在代码或者表达式的操作符之前换行; (3) 以上情况,可酌情处理,尽量保证方便阅读即可; (1) Visual Studio 可使用默认快捷键Ctrl +K,Ctrl +D 格式cs文件或cshtml等文件代码;提交代码之前应该格式化; (2) 过于长的代码块,可按照业务逻辑相关,使用外侧代码#region...#endregion将代码分块折叠; 正例: #region 测试方法 #endregion End 测试方法 (1) 因任何原因修改单行代码时,应加以注释,说明修改原因、时间和作者,如有相关需求或BUG应该同时标记需求或BUG编号; (2) 如有必要,应该在文件最顶部增加如下格式的注释说明;并在每次重要的变更之后增加详细的变更记录说明; (1) 所有供外部调用的类、方法、成员属性、枚举等都应该添加此类型的注释(summary),调用者可直接通过工具提示查阅相关说明,无需转入定义阅读代码和注释; (2) 文档注释一般对所注释的对象的用途,使用方式,参数列表和返回值等做出详细说明,方便调用者查阅; (3) 封装的通用js方法也可使用文档注释规范,语法应以js的注释规范为准; 说明:在Visual Studio内,js的文档注释同样具有工具提示的效果;在VS的编辑器内为js方法添加summary注释的快捷操作步骤:方法内第一行点击右键,选择“插入代码段”—选择“XMLComments”之后即可添加param或summary节点; (1) 类和类内成员注意修饰符,不要滥用public关键字,依据实际情况定义; (2) 常驻内存的常量,建议使用const修饰; 正例: /// private const int CHANNEL_ID = 175; (3) 单例模式的实现,除使用static修饰之外,应考虑是否需要volatile修饰; (4) partial(部分类)的使用:当一个类内代码块过多,或业务模块过于复杂时,可考虑将类拆分为多个文件保存;文件的命名应考虑指明当前类下的业务模块名称。 正例:当TUserBLL使用了partial修饰时,拆分为登录相关,后台管理相关2个部分类文件,应分别命名为:TUserBLL.Login.cs|TUserBLL.Management.cs (5) 常见修饰符的说明: public 公有的,类和成员的访问修饰符,无访问限制; internal 内部的,类和成员的访问修饰符,限制为程序集内访问; protected 受保护的,成员访问修饰符,限制为类内或派生类访问; protected internal 受保护或内部的,成员访问修饰符,限制为:程序集内可访问、其他程序集内的派生类可访问; private 私有的,成员访问修饰符,限制为类内访问; 说明:任何类、方法、参数、变量,严控访问范围,过于宽泛的访问范围,不利于模块解耦; (6) 其他C#关键字的使用规范和说明,参照微软官方文档: C# 关键字| Microsoft Docs https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/index (1) 循环体一定要掌握循环次数,尤其是用户级应用,避免超时; (2) 循环体内不允许直接声明任何类型的变量(包括值类型、对象和集合类型); 说明:应该将变量定义到循环体之外,在循环内赋值;循环体内调用的其他方法也要考虑期内部变量声明的情况; (3) js的循环体同样应该考虑性能问题; (1) 数据库的实体模型中,增加的非数据库字段属性,应在文档型注释中标记“[虚拟字段]”,方便调用者查阅; (2) 尽量避免匿名类的使用(包括但不限于Action的JsonResult); 说明:可使用数据表的Model、ViewModel、DataModel等通用对象作为被序列化的返回值对象; (3) 实体中的枚举类型字段,不要定义为int获其他值类型,建议直接定义枚举类型; 正例:public static UserType Type { get; set; } (4) 配置参数的值为Json或表中的字段为Json结构时,也应该考虑为其定义单独的数据模型,方便各应用的解析; (1) 字符串拼接尽量避免使用“+”或“+=”,少量拼接或格式化采用string.Format()方法,循环或大量拼接必须使用StringBuilder 对象; 说明:StringBuilder中拼接格式化的信息,可直接采用AppendFormat方法; (2) 常数数字的赋值,非int值的情况,应在数值末尾加以类型字母标识,减少隐式的类型转换; 正例: decimal decValue = 108.21M;//M表示decimal类型数值声明 float fltValue = 108.21F;//F表示float类型数值声明 long lgValue = 108L;//L表示long类型数值声明 (3) Hashtable的使用,在根据不同的业务条件加入不同的Key时,建议使用Key索引的形式赋值,不要采用Add()方法; 说明: 当因为业务判断导致添加了重复的Key,Add方法会抛出异常; 直接使用Key索引赋值,将会覆盖重复的Key和Value; 正例: int userId=1; Hashtable param =new Hashtable(); param["UserId"] =userId; (1) 尽量减少IList对象的ToList()方法调用(尤其是集合元素较多时); (2) 从数据源(缓存或数据库)取出的数据集合,不应该一次性取出过多数据;用户级别应用建议一次性获取不要超过100个元素;windows服务可适量增加但不建议超过1000个;业务需要时,应考虑分页处理; (1) 所有的Controller和Action都应该考虑过滤器和用户登录状态、权限的限定; (2) 业务代码尽量后置,视图的主要目的是展示和回传数据,尽量不要出现业务代码模块;控制器主要负责和业务层交互数据,复杂业务处理尽量后置到业务层(BLL); (3) 视图数据的展示,尽量将ViewBag等数据转换为强类型的实体,方便开发和阅读;dynamic等动态类型,无法识别和显示实体下的具体属性和文档型注释的工具提示; (4) 通用的视图应当通过部分页或其他方式封装为通用组件; 正例:用户提交订单、用户地址管理等多处会用到省市县行政区划联动选择的代码块,应当封装一个行政区划的下拉框联动组件; (5) 视图中某些js代码,或html代码动态加载的控制,应当尽量采用Razor的写法实现,放弃使用js的控制方式;减少页面的呈现代码量; (6) 不建议在Action内拼接HTML字符串输出视图上的html内容,可维护和扩展性较弱; (1) 所有数据库访问必须在数据层(DAL)进行,禁止在其他层访问数据库; (2) 所有脚本只能存在于存储过程和持久层的map文件中,禁止出现在DAL或其他层; (3) 为了方便阅读,请尽量将脚本规范化书写: SQL SERVER关键字全部大写; 表名、字段名、视图、自定义函数等数据库对象尽量书写时和定义的大小写一致; (4) 所有查询禁止出现“SELECT * FROM ”的写法,即便是需要全部字段也要逐个列出;如果数据库字段出现和Model不一致,“SELECT * FROM ”会导致ORM映射抛出异常; 说明:尽量缩减查询的字段数量,尤其是大文本数据的字段,非必要时不要查询返回; (5) 查询尽量使用无锁查询 WITH ( NOLOCK ); 说明:实时性极强(如账户余额、或更新后立即查询等操作)应该考虑放弃使用无锁查询; (6) map文件的SQL脚本可根据实际参数实现动态组装,并有缓存效果,但不建议业务关联性不太强的脚本共用同一个map方法; 说明:如果书写的查询脚本存在复杂查询,JOIN级联查询等,此类脚本只能适用于确实需要JOIN或复杂查询的方法调用,若调用者不需要复杂查询,应当创建新的查询脚本方法;不可共用; 正例:已存在的脚本使用LEFT JOIN连接了多个表,当调用者不需要关联这些表时,应考虑选择其他map方法或者新创建方法,不能共用; (7) COUNT计数时,推荐使用COUNT(1)或者COUNT(Id),不建议直接使用COUNT(*); (8) 通过SQL脚本判断满足指定条件的记录是否存在时,推荐使用语法EXISTS; 说明:使用关键字EXISTS和IF组合,通过判断返回值是1或0来判断,要查询的数据是否存在; IN的写法也应该使用EXISTS替代; 正例: IF (EXISTS(SELECT 1 FROM dbo.TUser WITH ( NOLOCK ) WHERE UserId = 1 )) SELECT 1 ELSE SELECT 0 反例:禁止直接使用以下写法: SELECT * FROM dbo.TUser WHERE UserId = 1 SELECT TOP 1 * FROM dbo.TUser WHERE UserId =1 SELECT COUNT(1) FROM dbo.TUser WHERE UserId = 1 (9) 使用iBatisNet的Update方法,不要轻易更新整个Model的所有字段,浪费资源,并且可能会导致bug;尽量只更新已修改的字段; 说明:尽量只传入需要修改的字段,必要时可定义为Hashtable等字典类型参数; (10) SQL SERVER 2012起,建议使用新的分页方法(OFFSET…FETCH); 说明:从执行计划来看,FETCH语法,比ROW_NUMBER()分页性能好很多,语法如下, OFFSET { integer_constant | offset_row_count_expression } { ROW | ROWS } FETCH { FIRST |NEXT} { integer_constant |fetch_row_count_expression } { ROW | ROWS } ONLY (11) 使用DELETE删除数据,务必谨慎考虑; 说明:数据无价,谨慎删除!必要情况下应考虑使用逻辑删除(通过字段标识为删除状态); (12) 事务的使用:如需使用事务,请务必确保事务有结束点;事务中只负责数据的更新操作,不应该将不必要的查询放入事务中进行; 说明:必须保证所有路径都有Commit或者RollBack,事务的使用,必须使用try…catch模块捕获异常,并在异常时RollBack; (13) 所有的数据库脚本禁止跨库访问; 说明:所有的T-SQL语句,不要添加数据库名称前缀的形式直接跨库访问;如确切需要跨库,应使用链接服务器(LINKEDSERVER)方式,或考虑其他解决方案; (14) 复杂的数据处理业务,应考虑创建存储过程; (15) 生产环境一般不建议手工修改数据,如必要,请务必谨慎检查脚本的正确性之后将脚本和相关需求发送给DBA执行 (1) 推荐使用Redis或Memcached缓存; (2) 缓存只允许在BLL(业务层)直接引用,不可在其他层出现直接调用; (3) 所有缓存的使用,要确保缓存数据的刷新及时性,否则会引起数据不一致的bug; (4) 缓存的KEY命名,必须按照既定的规则定义;建议使用树形结构定义KEY节点; (5) 使用缓存读取数据之前,务必确保配置了正确的缓存KEY,否则会导致读取数据失败; (6) 不可对已配置的缓存中的数据私自更换数据模型,会导致其他应用无法解析到正确的数据,出现未处理的异常; (7) 更新数据时,涉及展示数据、获取数据判断时,不可直接取缓存数据作为修改前的展示数据,防止将旧数据覆盖写入到数据库中; (8) 合理使用缓存:相对静态的数据、访问频率较高的数据应酌情使用缓存来读取,降低数据库访问压力;并应该根据实际的缓存命中率情况考虑设定缓存的时长; (9) Redis消息队列的使用:插入到消息队列的数据应保证正确性、并且简洁;队列由服务读取后操作,有一定的时间延迟,并且操作结果不可反馈到应用,因此要考虑实际应用场景; (1) 通用业务方法、模块应该考虑封装为WCF或WebAPI; (1) 生产环境的WCF,均应该采用TCP协议部署和引用(必须要外网引用的WCF除外); (2) 测试环境的WCF部署域名,建议使用和生产环境相同的设定(可通过hosts指向来访问),能保证调试和生产环境的一致性; (3) 禁止通过WCF传入和返回超大量的数据; (4) WCF的引用,应添加到BLL(业务层),不可引用至其他层; 说明:WCF虽然引用至BLL层,但配置节点应该手动添加到各个应用的Web.config或App.config中; (1) 传入的参数和返回值,尽量采用Json格式,并使用数据模型来定义,避免直接使用值类型或对象类型; 说明:值类型和对象类型的参数扩展性不好,如遇到增加返回值字段或者参数字段,不利于扩展; (2) 如果返回的数据为集合,并且量过大,应考虑使用分页方式返回数据,每页数据建议不超过100条; (3) 开放性的WCF接口或WebAPI务必考虑安全性控制; 说明:可通过私钥加时间戳的签名验证方式控制安全性;签名可采用MD5加密算法等实现;特殊接口如无法增加签名验证可考虑不增加该限制;有开发能力应该实现完善的OAuth2.0授权机制; (4) 调用WCF的方法,使用完毕后务必显式的直接调用WCF的关闭方法; 说明:开启WCF的连接会消耗大量服务器资源,务必及时关闭;也不可循环多次开启连接; (5) WCF的Service层、WebAPI的Action层尽量减少业务代码的耦合,将业务逻辑后置到BLL业务层; (6) 通用的WCF或者WebAPI接口,建议形成开发手册(开发规范文档); (1) 所有解决方案下不得私自引入前端组件、服务端组件,不得私自变更已有的组件或框架; (2) 通用工具层不得私自引入第三方组件,或变更、删除、新增通用方法; (3) 所有的资源文件(CSS文件,JS文件,图片文件)不得私自修改,必须以UI提供的文件为准; (4) 解决方案的调试,如果设置了本地IIS调试或其他特殊VS设置,请不要将配置提交到svn(或其他源代码管理工具),建议设置到user文件,并将user文件加入到svn的忽略列表;因为其他开发者肯定没有一致的IIS站点,会导致调试异常; (5) 不得擅自升级任何解决方案下任何项目的.NETFramework版本; (6) 不得擅自升级引入的所有第三方组件和dll文件的版本; (7) 所有项目下引入的第三方dll文件,应该放到对应的解决方案的指定文件夹下,并分类放置、提交到svn;防止其他开发者无法获取到引入的文件,导致编译失败; (8) 复杂项目的开发,建议先画对应的业务流程图;流程路径更严谨,开发思路更清晰,维护更方便; (9) 项目开发过程中建议记录下发布时需要上线的文件列表,防止发布时遗漏; .NET开发规范 标签:防止 序列化 渠道 站点 存在 gem asc 指定 链接服务器 原文地址:http://www.cnblogs.com/elvis-cnblogs/p/7093913.html1.1 命名法说明
1.2 常见命名规范
1.3 代码文件命名
二、代码格式化外观
2.1 代码行列展示
2.2 代码文件排版
三、程序代码注释规范
3.1 代码行内注释
3.2 文档型注释
四、常用.NET编程规范
4.1 类和类内成员修饰符的使用
4.2 循环代码块的使用
4.3 实体模型的使用
4.4 变量的合理赋值
4.5 集合(IList和List)的使用
4.6 MVC和Razor视图语法的规范
五、持久层(基于iBatisNet)和数据库规范
六、分布式缓存使用规范
七、WCF和WebAPI使用规范
7.1 封装WCF和WebAPI的原则
7.2 WCF的配置和引用
7.3 WCF和WebAPI的开发规范
八、Visual Studio解决方案使用