在SourceGenerator出现之前有一些重复性的代码,我会使用T4去生成,这样就可以一定程度上避免复制粘贴和可维护性也会更好一些。
在了解了一些SourceGenerator之后,就想尝试把现在项目里的一些T4换成SourceGenerator来实现,大部分场景应该都是没有问题的,可以直接用SourceGenerator替换,而且SourceGenerator可以根据编译信息动态的去生成,更加的智能和自动化。
接着来看一下我是如何使用SourceGenerator来代替T4生成代码的吧
Before首先来看一下修改之前的项目情况,项目结构是这样的
原来在Business项目里有一个T4模板,定义如下:
#
templatedebug="false"hostSpecific="true"language="C#"##outputextension=".generated.cs"encoding="utf-8"##AssemblyName="System.Core"##importnamespace="System"##importnamespace="System.Collections"##string[]types={"BlockType","BlockEntity","OperationLog","Reservation","ReservationPlace","ReservationPeriod","SystemSettings","Notice","DisabledPeriod"};#usingOpenReservation.Database;usingOpenReservation.Models;usingWeihanLi.EntityFramework;namespaceOpenReservation.Business{#foreach(varitemintypes){#publicpartialinterfaceIBLL#=item#:IEFRepositoryReservationDbContext,#=item#{}publicpartialclassBLL#=item#:EFRepositoryReservationDbContext,#=item#,IBLL#=item#{publicBLL#=item#(ReservationDbContextdbContext):base(dbContext){}}#}#}模板比较简单,动态生成的代码如下:
usingOpenReservation.Database;usingOpenReservation.Models;usingWeihanLi.EntityFramework;namespaceOpenReservation.Business{publicpartialinterfaceIBLLBlockType:IEFRepositoryReservationDbContext,BlockType{}publicpartialclassBLLBlockType:EFRepositoryReservationDbContext,BlockType,IBLLBlockType{publicBLLBlockType(ReservationDbContextdbContext):base(dbContext){}}publicpartialinterfaceIBLLBlockEntity:IEFRepositoryReservationDbContext,BlockEntity{}publicpartialclassBLLBlockEntity:EFRepositoryReservationDbContext,BlockEntity,IBLLBlockEntity{publicBLLBlockEntity(ReservationDbContextdbContext):base(dbContext){}}publicpartialinterfaceIBLLOperationLog:IEFRepositoryReservationDbContext,OperationLog{}publicpartialclassBLLOperationLog:EFRepositoryReservationDbContext,OperationLog,IBLLOperationLog{publicBLLOperationLog(ReservationDbContextdbContext):base(dbContext){}}publicpartialinterfaceIBLLReservation:IEFRepositoryReservationDbContext,Reservation{}publicpartialclassBLLReservation:EFRepositoryReservationDbContext,Reservation,IBLLReservation{publicBLLReservation(ReservationDbContextdbContext):base(dbContext){}}publicpartialinterfaceIBLLReservationPlace:IEFRepositoryReservationDbContext,ReservationPlace{}publicpartialclassBLLReservationPlace:EFRepositoryReservationDbContext,ReservationPlace,IBLLReservationPlace{publicBLLReservationPlace(ReservationDbContextdbContext):base(dbContext){}}publicpartialinterfaceIBLLReservationPeriod:IEFRepositoryReservationDbContext,ReservationPeriod{}publicpartialclassBLLReservationPeriod:EFRepositoryReservationDbContext,ReservationPeriod,IBLLReservationPeriod{publicBLLReservationPeriod(ReservationDbContextdbContext):base(dbContext){}}publicpartialinterfaceIBLLSystemSettings:IEFRepositoryReservationDbContext,SystemSettings{}publicpartialclassBLLSystemSettings:EFRepositoryReservationDbContext,SystemSettings,IBLLSystemSettings{publicBLLSystemSettings(ReservationDbContextdbContext):base(dbContext){}}publicpartialinterfaceIBLLNotice:IEFRepositoryReservationDbContext,Notice{}publicpartialclassBLLNotice:EFRepositoryReservationDbContext,Notice,IBLLNotice{publicBLLNotice(ReservationDbContextdbContext):base(dbContext){}}publicpartialinterfaceIBLLDisabledPeriod:IEFRepositoryReservationDbContext,DisabledPeriod{}publicpartialclassBLLDisabledPeriod:EFRepositoryReservationDbContext,DisabledPeriod,IBLLDisabledPeriod{publicBLLDisabledPeriod(ReservationDbContextdbContext):base(dbContext){}}}
我是在开发时动态生成的,听大师说也可以改成在编译的时候进行生成,不过我没去尝试过,有兴趣的可以了解一下