微服务中通过兄弟文件生成代码
Code generation via sibling file in micro-service
是否有一个 nuget 可以通过命令行(就像 EF 工具对添加迁移所做的那样)从我的实体(名称和属性)中包含的信息生成 "sibling" 代码(又名样板文件)?
最简单的方法可能是使用代码生成器生成所有样板代码。
尽管许多代码生成器使用他们自己的模型来定义领域实体,但它可以提高效率并节省大量工作量。
Telosys (https://www.telosys.org/) with C# templates ( https://github.com/telosys-templates-v3/csharp-web-mvc) 等一些工具可用于 .Net 项目。
在您的情况下,您只需要在 DSL 模型中重新定义您的实体(参见 https://www.telosys.org/dsl-syntax.html 这非常简单)
另请参阅以下回复:
How to generate whole boiler plate code for CRUD operations like visual studio using code?
我最终选择了 T4 文本模板,它基本上包括在每个文件夹中放置一个 .tt 文件。
为了为每个实体创建相应的文件,我不得不使用一些反射(这部分很棘手)
非常感谢最初创建 SaveOutput 方法的人。
我在这里粘贴了一个工作模板。很简单的一个,方便理解。
如果您使用的是 Resharper,我建议您安装 ForTea 插件。否则,处理模板会变得非常困难。
<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" #>
<#@ assembly name="$(TargetDir)MyProject.Shared.Domain.dll" #>
<#@ assembly name="$(TargetDir)MyProject.Shared.Common.dll" #>
<#@ assembly name="$(TargetDir)MyProject.Domain.dll" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="MyProject.Shared.Common.Helpers" #>
<#@ import namespace="MyProject.Shared.Common.Extensions" #>
<#@ import namespace="MyProject.Shared.Domain.Entities" #>
<#@ output extension=".txt" #>
<#
var types = FileHelper.GetTypes(typeof(IEntity),Assembly.LoadFrom(typeof(IEntity).Assembly.CodeBase.Replace("MyProject.Shared.Domain.dll","") + "MyProject.Domain.dll"));
foreach (var type in types) {
if(new[]
{
//////// Exclude ////////
"a"
//, "b"
//, "c"
/////////////////////////
}.Any(c => type.Name.Contains(c))) continue;
////////////////////////////////////////////// Your code //////////////////////////////////////////////
#>
namespace MyProject.Application.Messages
{
public static class <#=type.Name#>Message
{
public const string <#=type.Name#>NotFound = "The <#=type.Name.ToReadable()#> does not exist";
public const string <#=type.Name#>AlreadyExists = "The <#=type.Name.ToReadable()#> already exists";
}
}
<#
///////////////////////////////////////////////////////////////////////////////////////////////////////
SaveOutput(type.Name + "Message.cs");
}
#>
<#+
private void SaveOutput(string outputFileName) {
var templateDirectory = Path.GetDirectoryName(Host.TemplateFile);
if (templateDirectory == null) return;
var outputFilePath = Path.Combine(templateDirectory, outputFileName);
if(!File.Exists(outputFilePath)) File.WriteAllText(outputFilePath, this.GenerationEnvironment.ToString());
GenerationEnvironment.Remove(0, GenerationEnvironment.Length);
}
#>
是否有一个 nuget 可以通过命令行(就像 EF 工具对添加迁移所做的那样)从我的实体(名称和属性)中包含的信息生成 "sibling" 代码(又名样板文件)?
最简单的方法可能是使用代码生成器生成所有样板代码。 尽管许多代码生成器使用他们自己的模型来定义领域实体,但它可以提高效率并节省大量工作量。
Telosys (https://www.telosys.org/) with C# templates ( https://github.com/telosys-templates-v3/csharp-web-mvc) 等一些工具可用于 .Net 项目。
在您的情况下,您只需要在 DSL 模型中重新定义您的实体(参见 https://www.telosys.org/dsl-syntax.html 这非常简单)
另请参阅以下回复: How to generate whole boiler plate code for CRUD operations like visual studio using code?
我最终选择了 T4 文本模板,它基本上包括在每个文件夹中放置一个 .tt 文件。
为了为每个实体创建相应的文件,我不得不使用一些反射(这部分很棘手)
非常感谢最初创建 SaveOutput 方法的人。
我在这里粘贴了一个工作模板。很简单的一个,方便理解。
如果您使用的是 Resharper,我建议您安装 ForTea 插件。否则,处理模板会变得非常困难。
<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" #>
<#@ assembly name="$(TargetDir)MyProject.Shared.Domain.dll" #>
<#@ assembly name="$(TargetDir)MyProject.Shared.Common.dll" #>
<#@ assembly name="$(TargetDir)MyProject.Domain.dll" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="MyProject.Shared.Common.Helpers" #>
<#@ import namespace="MyProject.Shared.Common.Extensions" #>
<#@ import namespace="MyProject.Shared.Domain.Entities" #>
<#@ output extension=".txt" #>
<#
var types = FileHelper.GetTypes(typeof(IEntity),Assembly.LoadFrom(typeof(IEntity).Assembly.CodeBase.Replace("MyProject.Shared.Domain.dll","") + "MyProject.Domain.dll"));
foreach (var type in types) {
if(new[]
{
//////// Exclude ////////
"a"
//, "b"
//, "c"
/////////////////////////
}.Any(c => type.Name.Contains(c))) continue;
////////////////////////////////////////////// Your code //////////////////////////////////////////////
#>
namespace MyProject.Application.Messages
{
public static class <#=type.Name#>Message
{
public const string <#=type.Name#>NotFound = "The <#=type.Name.ToReadable()#> does not exist";
public const string <#=type.Name#>AlreadyExists = "The <#=type.Name.ToReadable()#> already exists";
}
}
<#
///////////////////////////////////////////////////////////////////////////////////////////////////////
SaveOutput(type.Name + "Message.cs");
}
#>
<#+
private void SaveOutput(string outputFileName) {
var templateDirectory = Path.GetDirectoryName(Host.TemplateFile);
if (templateDirectory == null) return;
var outputFilePath = Path.Combine(templateDirectory, outputFileName);
if(!File.Exists(outputFilePath)) File.WriteAllText(outputFilePath, this.GenerationEnvironment.ToString());
GenerationEnvironment.Remove(0, GenerationEnvironment.Length);
}
#>