在ASP.NET Core中引入了DI,並且通過構造函數注入參數,控制器中會大量使用DI注入各種的配置參數,如果配置注入的參數比較多,而且各個控制器需要的配置參數都基本一樣的話,那麼不斷重復的復制黏貼代碼提供相應的構造函數,效率低效也,因此使用T4模板生成控制器的構造函數 ,這也得益於C#對分部類(partial)的支持。

圖中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模板的控制器必須設置為分部類,而且命名空間要一致。