.NET Core – 自定义项目模板

前言:

 前面介绍 自定义项目模板 中介绍了一种简单的方式——通过创建项目导出为项目模板方式实现。本次将采用dotenet cil(手脚架)来创建项目模板。

 那么,我们首先看下当前dotnet 支持的项目模板:

  

  可以看到当前dotnet中已经提供了很多模板项目,那么如何根据项目开发的积累内容通过dotnet cli创建一个自己的项目来提升开发效率呢?

1、实现自定义项目模板

 自定义模板项目模板肯定就需要模板实现,本次就使用使用之前文章中项目结构作为模板项目来实现自定义项目模板

 

 接下跟着步骤来创建模板项目

  • 创建模板配置文件

   在项目根文件夹中创建文件夹:.template.config  并在目录下创建 template.json 。如下图:

   

  • 定义项目模板相关信息

   修改template.json内容为以下内容:

{
    "author": "cwsheng", //必须
    "classifications": [ "Web/WebAPI" ], //必须,这个对应模板的Tags
    "name": "ApiTmp", //必须,这个对应模板的Templates
    "identity": "ApiTemplate", //可选,模板的唯一名称
    "shortName": "apitmp", //必须,这个对应模板的Short Name
    "tags": {
      "language": "C#" ,
      "type":"project"
    },
    "sourceName": "ApiTemplate",  // 可选,要替换的名字
    "preferNameDirectory": true  // 可选,添加目录  
}

   注意:shortName和sourceName

    • author:模板作者
    • classifications:模板特征标识。上文举例的配置是因为我自定义的模板包括了console和webapi。
    • identity:此模板的唯一名称
    • name:用户看到的模板名称
    • shortName:短名称。当使用CLI命令创建模板项目时,使用短名称将利于使用。
    • sourceName:模板替换的关键文本,使用时需要注意,要选择合适的替换文本,不然容易误伤代码。
  • 项目模板安装

   接下来进入项目目录,将这个模板安装到cli中。使用 dotnet new -i  进行模板的安装。

dotnew new -i TempDemo

  

   卸载项目模板:

dotnet new -u 模板目录
  • 应用项目模板

   使用命令创建项目:

dotnet new apiTmp -n Test -o .

apiTmp:是模板配置文件中指定的shortName。

-n:指定的是将项目中出现的所有文本MyJob替换为Test,因为配置中sourceName是ApiTemplate,可按需配置。

-o:指定的是生成项目输出目录,上述命令生成项目输出到当前目录。

   结果如下图:    

    

 

  到此通过dotnet cli创建项目模板已完成,但仅仅这样完全不能满足日常工作需求。
  如:
A项目需要日志记录,但B项目不需要日志记录;A项目需要制定PG数据库作为存储方式,B项目需要制定MySQL作为存储方式。

  那么这些问题能否在项目创建时根据设置而满足项目需求呢?

2、模板项目进阶用法

  • 文件过滤:根据参数过滤制定文件和代码内容

   a) 定义参数:在 template.json  中添加以下内容:EnableAuditLog-参数名称

{
  //……
  "symbols": {
    //是否使用审计日志功能
    "EnableAuditLog": {
      "type": "parameter", //它是参数
      "dataType": "bool", //bool类型的参数
      "defaultValue": "false" //默认是不启用
    }
  },
  "sources": [
    {
      "modifiers": [
        {
          "condition": "(!EnableAuditLog)", //条件,由EnableAuditLog参数决定
          "exclude": [ //排除下面的文件
            "AuditLogDemo/Fliters/AuditLogActionFilter.cs"
          ]
        }
      ]
    }
  ]
}

  b) 取消审计日志生效位置:

  

   c) 重新生成模板,查看当前模板支持的参数:

   

  d) 创建项目检查设置是否生效:

  

  • 选择执行:根据变量值选择程序集引用

   a) 添加参数:DbType指定选项数据库类型

  "symbols": {
    //数据源类型"DbType": {
      "type": "parameter", //它是参数
      "datatype": "choice", //选项类型
      "choices": [ //选项取值
        {
          "choice": "MsSQL",
          "description": "MS SQL Server"
        },
        {
          "choice": "MySQL",
          "description": "MySQL"
        },
        {
          "choice": "PgSQL",
          "description": "PostgreSQL"
        },
        {
          "choice": "SQLite",
          "description": "SQLite"
        },
        {
          "choice": "None",
          "description": "None"
        }
      ],
      "defaultValue": "None",
      "description": "The type of SQL to use"
    },
    "MsSQL": {
      "type": "computed",
      "value": "(DbType == \"MsSQL\")"
    },
    "MySQL": {
      "type": "computed",
      "value": "(DbType == \"MySQL\")"
    },
    "PgSQL": {
      "type": "computed",
      "value": "(DbType == \"PgSQL\")"
    },
    "SQLite": {
      "type": "computed",
      "value": "(DbType == \"SQLite\")"
    },
    "None": {
      "type": "computed",
      "value": "(DbType == \"None\")"
    }
  }

   b) 修改项目文件:根据条件选择对应程序集

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup Condition="'$(None)'!='True'">
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.8" />
  </ItemGroup>
  <ItemGroup  Condition="'$(SQLite)' == 'True'">
    <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.8" />
  </ItemGroup>
  <ItemGroup  Condition="'$(MsSQL)' == 'True'">
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.8" />
  </ItemGroup>
  <ItemGroup  Condition="'$(PgSQL)' == 'True'">
    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.4" />
  </ItemGroup>
</Project>

   c) 使用数据库处,同步处理

#if (!None)
            //审计日志存储
            services.AddDbContext<AuditLogDBContent>(options =>
            {
                string conn = Configuration.GetConnectionString("LogDB");
#if Sqlite
                options.UseSqlite(conn, options =>
                {
                    options.MigrationsAssembly("AuditLogDemo");
                });
#endif
#if PgSQL
                options.UseNpgsql(conn);
#endif

#if MsSQL
                options.UseSqlServer(conn);
#endif

            });
#endif

   d) 更新模板后,查看已生成了对应参数

     

    e) 创建项目查看生效情况:    

//不使用数据库
dotnet new apiTmp -n AA -D None

//使用PG数据库
dotnet new apiTmp -n BB -D PgSQL

    

    可以看到项目引用和程序代码都根据传入参数生成了。    

3、项目模板打包发布

  好东西当然不能只给自己使用,而应该怎么将生成的模板给大家使用呢?——Nuget 包发布

 a)在模板根目录创建一个 nuspec文件:apiTmp.nuspec

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="//schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
  <metadata>
    <id>apiTmp</id>
    <version>1.0.0</version>
    <description> WebApi Template </description>
    <authors>cwshegn</authors>
    <packageTypes>
      <packageType name="Template" />
    </packageTypes>
  </metadata>
</package>

 b)使用Nuget Pack 命令打包  

 nuget pack apiTmp.nuspec -OutputDirectory .

 c)  发布到nuget服务,给小伙伴们下载使用

总结:

 通过dotnet cli 创建的模板项目,能更方便的根据项目需求生成对应的项目结构,提升开发效率。

 可以动手把积累的好项目打包成一个模板项目给小伙伴们使用

参考:

//devblogs.microsoft.com/dotnet/how-to-create-your-own-templates-for-dotnet-new/

//github.com/dotnet/dotnet-template-samples

//docs.microsoft.com/en-us/dotnet/core/tools/dotnet-new

//docs.microsoft.com/en-us/nuget/install-nuget-client-tools