利用T4模板生成ASP.NET Core控制器的构造函数和参数
前言
在ASP.NET Core中引入了DI,并且通过构造函数注入参数,控制器中会大量使用DI注入各种的配置参数,如果配置注入的参数比较多,而且各个控制器需要的配置参数都基本一样的话,那么不断重复的复制黏贴代码提供相应的构造函数,效率低效也,因此使用T4模板生成控制器的构造函数 ,这也得益于C#对分部类(partial)的支持。
T4模板生成控制器构造函数
图中CtrlTemplate.tt为模板文件,CtrlNames.txt为需要使用T4生成代码的控制器名称文件,CtrlTemplate.cs为T4模板生成的文件。
CtrlNames.txt文件内容:
Values
Account
CtrlTemplate.tt代码:
1 <#@ template language="C#" debug="false" hostspecific="true"#> 2 <#@ assembly name="System.Core" #> 3 <#@ import namespace="System.Linq" #> 4 <#@ import namespace="System.Text" #> 5 <#@ import namespace="System.Collections.Generic" #> 6 <#@ output extension=".cs" #> 7 using ApiCoreTest; 8 using EFDbContext; 9 using Microsoft.AspNetCore.Mvc; 10 using Microsoft.Extensions.Logging; 11 using Microsoft.Extensions.Options; 12 13 namespace ApiCoreTest.Controllers 14 { 15 <# 16 //获取项目的根目录 17 var solutionsPath = Host.ResolveAssemblyReference("$(SolutionDir)"); 18 //获取配置文件 19 var lines = System.IO.File.ReadAllLines(solutionsPath + @"/src/ApiCoreTest/Controllers/Template/CtrlNames.txt"); 20 foreach(var name in lines) 21 {#> 22 public partial class <#= name#>Controller : Controller 23 { 24 IOptions<ConfigModel> _config; 25 ILogger<<#= name#>Controller> _logger; 26 ApplicationDbContext _db; 27 public <#= name#>Controller(IOptions<ConfigModel> config, ILogger<<#= name#>Controller> logger, ApplicationDbContext db) 28 { 29 _config = config; 30 _logger = logger; 31 _db = db; 32 } 33 } 34 <#}#> 35 }
模板生成的文件CtrlTemplate.cs 内容:
1 using ApiCoreTest; 2 using EFDbContext; 3 using Microsoft.AspNetCore.Mvc; 4 using Microsoft.Extensions.Logging; 5 using Microsoft.Extensions.Options; 6 7 namespace ApiCoreTest.Controllers 8 { 9 public partial class ValuesController : Controller 10 { 11 IOptions<ConfigModel> _config; 12 ILogger<ValuesController> _logger; 13 ApplicationDbContext _db; 14 public ValuesController(IOptions<ConfigModel> config, ILogger<ValuesController> logger, ApplicationDbContext db) 15 { 16 _config = config; 17 _logger = logger; 18 _db = db; 19 } 20 } 21 public partial class AccountController : Controller 22 { 23 IOptions<ConfigModel> _config; 24 ILogger<AccountController> _logger; 25 ApplicationDbContext _db; 26 public AccountController(IOptions<ConfigModel> config, ILogger<AccountController> logger, ApplicationDbContext db) 27 { 28 _config = config; 29 _logger = logger; 30 _db = db; 31 } 32 } 33 }
使用了模板的控制器:
1 namespace ApiCoreTest.Controllers 2 { 3 [Route("api/[controller]")] 4 public partial class ValuesController : Controller 5 { 6 [HttpGet] 7 public string Gets() 8 { 9 var val = JsonConvert.SerializeObject(_config.Value); 10 _logger.LogDebug(val); 11 return val; 12 } 13 } 14 }
1 namespace ApiCoreTest.Controllers 2 { 3 public partial class AccountController : Controller 4 { 5 public IActionResult Test() 6 { 7 var val = JsonConvert.SerializeObject(_config.Value); 8 _logger.LogDebug(val); 9 return Content(val); 10 } 11 } 12 }
注意
使用了T4模板的控制器必须设置为分部类,而且命名空间要一致。