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

不需要iis的网站开发青海省住房和城乡建设厅的官方网站

不需要iis的网站开发,青海省住房和城乡建设厅的官方网站,庆元县建设局网站,你的网站尚未进行备案使用 Source Generator 代替 T4 动态生成代码Intro在 Source Generator 出现之前有一些重复性的代码#xff0c;我会使用 T4 去生成#xff0c;这样就可以一定程度上避免复制粘贴和可维护性也会更好一些。在了解了一些 Source Generator 之后#xff0c;就想尝试把现在项目里… 使用 Source Generator 代替 T4 动态生成代码Intro在 Source Generator 出现之前有一些重复性的代码我会使用 T4 去生成这样就可以一定程度上避免复制粘贴和可维护性也会更好一些。在了解了一些 Source Generator 之后就想尝试把现在项目里的一些 T4 换成 Source Generator 来实现大部分场景应该都是没有问题的可以直接用 Source Generator 替换而且 Source Generator 可以根据编译信息动态的去生成更加的智能和自动化。接着来看一下我是如何使用 Source Generator 来代替 T4 生成代码的吧Before首先来看一下修改之前的项目情况项目结构是这样的原来在 Business 项目里有一个 T4 模板定义如下# template  debugfalse hostSpecifictrue languageC# # # output extension.generated.cs encodingutf-8 # # Assembly NameSystem.Core # # import namespaceSystem # # import namespaceSystem.Collections # #string[] types  {BlockType,BlockEntity,OperationLog,Reservation,ReservationPlace,ReservationPeriod,SystemSettings,Notice,DisabledPeriod}; # using OpenReservation.Database; using OpenReservation.Models; using WeihanLi.EntityFramework;namespace OpenReservation.Business { # foreach (var item in types){ #public partial interface IBLL# item #: IEFRepositoryReservationDbContext, # item #{}public partial class BLL# item # : EFRepositoryReservationDbContext, # item #,  IBLL# item #{public BLL# item #(ReservationDbContext dbContext) : base(dbContext){}} #   }  # } 模板比较简单动态生成的代码如下using OpenReservation.Database; using OpenReservation.Models; using WeihanLi.EntityFramework;namespace OpenReservation.Business {public partial interface IBLLBlockType: IEFRepositoryReservationDbContext, BlockType{}public partial class BLLBlockType : EFRepositoryReservationDbContext, BlockType,  IBLLBlockType{public BLLBlockType(ReservationDbContext dbContext) : base(dbContext){}}public partial interface IBLLBlockEntity: IEFRepositoryReservationDbContext, BlockEntity{}public partial class BLLBlockEntity : EFRepositoryReservationDbContext, BlockEntity,  IBLLBlockEntity{public BLLBlockEntity(ReservationDbContext dbContext) : base(dbContext){}}public partial interface IBLLOperationLog: IEFRepositoryReservationDbContext, OperationLog{}public partial class BLLOperationLog : EFRepositoryReservationDbContext, OperationLog,  IBLLOperationLog{public BLLOperationLog(ReservationDbContext dbContext) : base(dbContext){}}public partial interface IBLLReservation: IEFRepositoryReservationDbContext, Reservation{}public partial class BLLReservation : EFRepositoryReservationDbContext, Reservation,  IBLLReservation{public BLLReservation(ReservationDbContext dbContext) : base(dbContext){}}public partial interface IBLLReservationPlace: IEFRepositoryReservationDbContext, ReservationPlace{}public partial class BLLReservationPlace : EFRepositoryReservationDbContext, ReservationPlace,  IBLLReservationPlace{public BLLReservationPlace(ReservationDbContext dbContext) : base(dbContext){}}public partial interface IBLLReservationPeriod: IEFRepositoryReservationDbContext, ReservationPeriod{}public partial class BLLReservationPeriod : EFRepositoryReservationDbContext, ReservationPeriod,  IBLLReservationPeriod{public BLLReservationPeriod(ReservationDbContext dbContext) : base(dbContext){}}public partial interface IBLLSystemSettings: IEFRepositoryReservationDbContext, SystemSettings{}public partial class BLLSystemSettings : EFRepositoryReservationDbContext, SystemSettings,  IBLLSystemSettings{public BLLSystemSettings(ReservationDbContext dbContext) : base(dbContext){}}public partial interface IBLLNotice: IEFRepositoryReservationDbContext, Notice{}public partial class BLLNotice : EFRepositoryReservationDbContext, Notice,  IBLLNotice{public BLLNotice(ReservationDbContext dbContext) : base(dbContext){}}public partial interface IBLLDisabledPeriod: IEFRepositoryReservationDbContext, DisabledPeriod{}public partial class BLLDisabledPeriod : EFRepositoryReservationDbContext, DisabledPeriod,  IBLLDisabledPeriod{public BLLDisabledPeriod(ReservationDbContext dbContext) : base(dbContext){}} } 我是在开发时动态生成的听大师说也可以改成在编译的时候进行生成不过我没去尝试过有兴趣的可以了解一下 https://docs.microsoft.com/en-us/visualstudio/modeling/run-time-text-generation-with-t4-text-templatesAfter使用 Source Generator 分成了两步第一步还是比较手动的保留了上面的 types 数组第二步则是自动的根据编译的信息动态的获取 types 数组首先我们要确定哪个项目是要动态生成代码的项目哪个项目是要写 Source Generator 的项目原来我们用 T4 生成代码的项目(Business)就是我们要动态生成代码的项目也就是这个项目应该是引用 Source Generator 的项目那我们 Source Generator 应该要放在哪个项目里呢理论上来说要生成代码的项目哪一个都是可以的新建一个项目也是可以的Business 直接依赖于 Database 项目所以我选择了 Database 项目来实现 Source GeneratorUpdate1首先我们需要配置 Source Generator 环境首先为我们要写 Generator 的项目增加对 Microsoft.CodeAnalysis.CSharp 的引用PackageReference IncludeMicrosoft.CodeAnalysis.CSharp Version3.9.0 / 因为 Source Generator 有外部依赖所以需要声明依赖项和上一篇文章类似在项目文件中增加下面的配置PropertyGroupGetTargetPathDependsOn;GetDependencyTargetPaths/GetTargetPathDependsOn /PropertyGroup ItemGroupPackageReference IncludeMicrosoft.CodeAnalysis.CSharp Version3.9.0 / /ItemGroup ItemGroupPackageReference IncludeWeihanLi.EntityFramework Version2.0.0-preview-* GeneratePathPropertytrue / /ItemGroup Target NameGetDependencyTargetPathsItemGroupTargetPathWithTargetPlatformMoniker Include$(PKGWeihanLi_EntityFramework)\lib\netstandard2.1\WeihanLi.EntityFramework.dll IncludeRuntimeDependencyfalse //ItemGroup /Target 然后要动态生成代码的项目也需要配置一下只需要修改项目文件原来的 T4 模板可以删掉了可以参考下面的配置PropertyGroupEmitCompilerGeneratedFilestrue/EmitCompilerGeneratedFiles /PropertyGroup ItemGroupProjectReference Include..\OpenReservation.Database\OpenReservation.Database.csprojOutputItemTypeAnalyzer / /ItemGroup 在 ProjectReference 中声明 OutputItemTypeAnalyzer 以使用 Generator 的功能通过配置 EmitCompilerGeneratedFiles 以生成动态代码帮助我们调试之后就开始写我们的 Generator 了最终代码如下[Generator] public class ServiceGenerator : ISourceGenerator {public void Initialize(GeneratorInitializationContext context){}public void Execute(GeneratorExecutionContext context){var types  new[]{BlockType,BlockEntity,OperationLog,Reservation,ReservationPlace,ReservationPeriod,SystemSettings,Notice,DisabledPeriod};var codeBuilder  new StringBuilder();codeBuilder.AppendLine( using OpenReservation.Database; using OpenReservation.Models; using WeihanLi.EntityFramework;namespace OpenReservation.Business {);foreach (var item in types){codeBuilder.AppendLine($public partial interface IBLL{item}: IEFRepositoryReservationDbContext, {item}{{}}public partial class BLL{item} : EFRepositoryReservationDbContext, {item},  IBLL{item}{{public BLL{item}(ReservationDbContext dbContext) : base(dbContext){{}}}});}codeBuilder.AppendLine(});var codeText  codeBuilder.ToString();context.AddSource(nameof(ServiceGenerator), codeText);} } 此时我们的 Generator 已经可以工作了生成的代码和上面的完全一样而且生成的代码可以不需要保存在代码库里了编译的时候会动态生成已经完全可以取代 T4 了详细修改可以参考这个 Commithttps://github.com/OpenReservation/ReservationServer/commit/8a723ba652a10fb393e90bf70923631f58294da8Update2接着上面的修改虽然已经代替了 T4但是似乎并不能够体现出 Source Generator 的优势啊于是就想再改一版利用编译信息自动的获取上面的 types 数组因为 types 不是随便写的是 model 的名字所以从编译信息中获取理论上来说是可以做到的于是有了第二版的实现实现代码如下[Generator] public class ServiceGenerator : ISourceGenerator {public void Initialize(GeneratorInitializationContext context){// Debugger.Launch();}public void Execute(GeneratorExecutionContext context){// 从编译信息中获取 DbSet 类型var dbContextType  context.Compilation.GetTypeByMetadataName(typeof(DbSet).FullName);// 从编译信息中获取 ReservationDbContext 类型var reservationDbContextType  context.Compilation.GetTypeByMetadataName(typeof(ReservationDbContext).FullName);// 获取 ReservationDbContext 中的 DbSet 属性var propertySymbols  reservationDbContextType.GetMembers().OfTypeIMethodSymbol().Where(x  x.IsVirtual x.MethodKind  MethodKind.PropertyGet x.ReturnType is INamedTypeSymbol{IsGenericType: true,IsUnboundGenericType: false,} typeSymbol ReferenceEquals(typeSymbol.ConstructedFrom.ContainingAssembly, dbContextType.ContainingAssembly)).ToArray();// 获取属性的返回值var propertyReturnType  propertySymbols.Select(r  ((INamedTypeSymbol)r.ReturnType)).ToArray();// 获取属性泛型类型参数并获取泛型类型参数的名称var modelTypeNames  propertyReturnType.Select(t  t.TypeArguments).SelectMany(x  x).Select(x  x.Name).ToArray();var codeBuilder  new StringBuilder();codeBuilder.AppendLine( using OpenReservation.Database; using OpenReservation.Models; using WeihanLi.EntityFramework;namespace OpenReservation.Business {);foreach (var item in modelTypeNames){codeBuilder.AppendLine($ public partial interface IBLL{item}: IEFRepositoryReservationDbContext, {item}{{}}public partial class BLL{item} : EFRepositoryReservationDbContext, {item},  IBLL{item} {{public BLL{item}(ReservationDbContext dbContext) : base(dbContext){{}} }});}codeBuilder.AppendLine(});var codeText  codeBuilder.ToString();// 添加要动态生成的代码context.AddSource(nameof(ServiceGenerator), codeText);} } 除了上面 Generator 的修改之外还需要增加 EFCore 依赖项这也是目前使用 SourceGenerator 的一个痛点我的 EF 扩展 WeihanLi.EntityFramework 已经依赖了 EFCore 但还是需要再声明一下声明方式和前面类似  ItemGroupPackageReference IncludeWeihanLi.EntityFramework Version2.0.0-preview-* GeneratePathPropertytrue /PackageReference IncludeMicrosoft.EntityFrameworkCore Version5.0.5 GeneratePathPropertytrue //ItemGroupTarget NameGetDependencyTargetPathsItemGroupTargetPathWithTargetPlatformMoniker Include$(PKGWeihanLi_EntityFramework)\lib\netstandard2.1\WeihanLi.EntityFramework.dll IncludeRuntimeDependencyfalse /TargetPathWithTargetPlatformMoniker Include$(PKGMicrosoft_EntityFrameworkCore)\lib\netstandard2.1\Microsoft.EntityFrameworkCore.dll IncludeRuntimeDependencyfalse //ItemGroup/Target 这样我们就可以通过 Source Generator 动态的自动生成 service 代码了以后新加表只需要在 ReservationDbContext 中加入新的表就可以了编译器也会自动生成新加表的服务类不需要再手动配置 types 数组了舒服~~More通过上面的示例再次戳到了痛点希望后面的版本更新中能够有所优化也希望 VS 能够提供更有力的支持。以上就是所有内容了希望能够对你有所帮助上面的示例代码可以从 https://github.com/OpenReservation/ReservationServer 进行获取ReferencesC# 强大的新特性 Source Generatorhttps://docs.microsoft.com/en-us/visualstudio/modeling/design-time-code-generation-by-using-t4-text-templates?viewvs-2019https://docs.microsoft.com/en-us/visualstudio/modeling/run-time-text-generation-with-t4-text-templates?viewvs-2019https://github.com/OpenReservation/ReservationServer/tree/9d2e0987d12143d297d4233bc37c06785bfa0cff/OpenReservation.Businesshttps://github.com/OpenReservation/ReservationServer/commit/8a723ba652a10fb393e90bf70923631f58294da8https://github.com/OpenReservation/ReservationServer/blob/dev/OpenReservation.Database/ServiceGenerator.cshttps://github.com/OpenReservation/ReservationServer
http://www.huolong8.cn/news/130230/

相关文章:

  • 网站开发学的啥网站网站制作网站的
  • 石家庄专业网站制wordpress顶部高度
  • 拐角型网站华为云建站官网
  • 网站建设佰首选金手指十05网全部答案数学
  • 单页电影网站源码wordpress检验上传的文档
  • 办个网站多少钱房屋平面图在线制作网站
  • wordpress设置中改网站美食网站建设策划报告
  • 怎样建手机网站广州企业网站制作公司
  • 几度设计网站上海哪家公司做网站比较好
  • 网站建设中存在的问题东莞有哪些好的网站建设公司
  • 做网站需要什么费用怎么和网站主联系方式
  • 二级域名网站可以做关键词优化吗高端建造
  • 境外电商网站建设北仑静态网站建设
  • 传播公司可以做门户网站吗百度快照优化推广
  • 专业免费网站建设一般外汇网站建设制作
  • 做网站 怎么连到数据库wordpress app页面模板
  • 企业做可信网站认证的好处图床外链生成工具
  • 高港区企业网站建设wordpress图书页面
  • 云服务器网站解析凡科小程序建站官网
  • 韩国做暖暖网站html5做的网站代码
  • 郑州平台网站建设企业网站html5
  • 成都便宜网站建设公司哪家好wordpress柳城
  • 网站建设需要哪些材料如何避免网站被攻击
  • wordpress 仿站 教程网深圳网站建设公
  • 网站建设制作报价宜都网站设计
  • 排名好的网站关键词优化企业wordpress 官网主题下载
  • 网站如何设定关键词深圳前十名代运营公司
  • 常德海关网站app开发模板
  • 模板的网站都有哪些内容机构网站建设需要交费吗
  • 深圳网站开发费用如何细分行业 做网站赚钱