eShopOnAbp重命名工具

本文写于 2021 年,示例代码面向当时的 eShopOnAbp 项目结构。后续版本目录和命名可能已有变化,使用前建议先在临时目录中验证替换结果。

eShopOnAbp项目架构

eShopOnAbp 是 ABP 团队基于 ABP 框架构建的微服务参考解决方案。它以实际案例展示了 ABP 框架在云原生微服务应用中的使用方式,目标是提供一个功能较完整的参考应用。这个项目的灵感来自 eShopOnContainers,同时也演示了如何用 ABP 框架实现类似架构。

为了更方便地把 eShopOnAbp 中的代码引入自己的项目,本文提供一个简单的重命名工具思路。

构造函数

创建一个控制台项目,然后创建 RenameProgram 类,并添加以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
protected string InPath { get; set; }
protected string OutPath { get; set; }
protected string CompanyName { get; set; }
protected string ProjectName { get; set; }
protected string FullName { get; set; }

public RenameProgram(string inPath, string outPath, string projectName, string companyName = null)
{
InPath = inPath;
OutPath = outPath;
ProjectName = projectName;
CompanyName = companyName;
FullName = string.Format("{1}{0}", projectName, !string.IsNullOrWhiteSpace(companyName) ? companyName + "." : "");
}

RenameProgram 的构造函数定义了四个参数:

  • inPath:输入目录,也就是 eShopOnAbp 源码所在目录
  • outPath:输出目录,也就是重命名后的项目保存目录
  • projectName:项目名称
  • companyName:公司名称(可选)

RenameProgram 会将 eShopOnAbp 重命名为 companyName.projectNameprojectName

待处理的文件

_includeFiles 中定义了 RenameProgram 需要处理的文件类型。这里排除了 .md 文件,因为文档里的部分链接也包含 eShopOnAbp,直接替换容易误伤。

1
2
//此处未包含md文件
private static readonly string _includeFiles = ".original,.yml,.yaml,.cs,.cshtml,.js,.ts,.csproj,.sln,.xml,.config,.dotsettings,.json,.txt,.html,.gitignore,.ps1,.xaml,.plist,.local,.tpl,dockerfile";

不在 _includeFiles 中的文件类型不会做内容替换。

1
2
3
4
5
6
7
8
9
10
11
/// <summary>
/// 是否跳过
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
private bool isSkip(string file)
{
if (string.IsNullOrWhiteSpace(file)) return true;
var skipFiles = _includeFiles.Split(',');
return !skipFiles.Contains(file.ToLower());
}

重命名策略

  • 命名空间替换为完整名称(FullName),例如 EShopOnAbp.namespace EShopOnAbp
  • 其他名称替换为项目名称(ProjectName),例如 EShopOnAbpeShopOnAbpeshoponabp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/// <summary>
/// 替换名称
/// </summary>
/// <param name="data"></param>
/// <param name="extension"></param>
/// <returns></returns>
private string replaceData(string data, string extension = null)
{
if (string.IsNullOrWhiteSpace(data)) return data;
data = data.Replace(InPath, OutPath);
data = data.Replace("EShopOnAbp.", FullName + ".", StringComparison.Ordinal);
data = data.Replace("namespace EShopOnAbp", "namespace " + FullName, StringComparison.Ordinal);
data = data.Replace("EShopOnAbp", ProjectName, StringComparison.Ordinal);

if (!string.IsNullOrWhiteSpace(extension) && extension == ".js")
{
var tempName = ProjectName.Substring(0, 1).ToLower() + ProjectName.Substring(1);
data = data.Replace("eShopOnAbp", tempName, StringComparison.Ordinal);//js only
}
else
{
data = data.Replace("eShopOnAbp", ProjectName, StringComparison.Ordinal);
}

data = data.Replace("eshoponabp.", FullName.ToLower() + ".", StringComparison.Ordinal);
data = data.Replace("eshoponabp", ProjectName.ToLower(), StringComparison.Ordinal);
return data;
}

重命名文件

  • 遍历当前目录下的文件。对于空文件、不包含 eshoponabp 关键字的文件,或被排除的文件类型,直接复制到输出目录;其他文件先经过 replaceData() 替换,再写入输出目录。
  • 递归遍历子目录,但跳过 .git.vsbinobjnode_modules
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/// <summary>
/// 重命名
/// </summary>
/// <param name="path"></param>
private void Rename(string path)
{
var outputPath = replaceData(path);
if (!Directory.Exists(outputPath))
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("find: " + outputPath);
Directory.CreateDirectory(outputPath);
}

var files = Directory.GetFiles(path);
foreach (var file in files)
{
var fileInfo = new FileInfo(file);
var outputFile = replaceData(file);
var data = File.ReadAllText(file);
var extension = string.IsNullOrWhiteSpace(fileInfo.Extension) ? fileInfo.Name : fileInfo.Extension;
if (string.IsNullOrWhiteSpace(data) || !data.Contains("EShopOnAbp", StringComparison.OrdinalIgnoreCase) || isSkip(extension))
{
File.Copy(file, outputFile);
}
else
{
var outputData = replaceData(data, extension);
File.WriteAllText(outputFile, outputData);
}
}

var directories = Directory.GetDirectories(path);
foreach (var directory in directories)
{
if (directory.EndsWith(".git") || directory.EndsWith(".vs") || directory.EndsWith("bin") || directory.EndsWith("obj") || directory.EndsWith("node_modules"))
{
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine("skip: " + directory);
continue;
}
Rename(directory);
}
}

运行代码

Program > Main 中添加以下代码:

1
2
var renameProgram = new RenameProgram("{输入目录}", "{输出目录}", "{项目名称}", "{公司名称}");
renameProgram.Rename();

运行项目并等待执行完成后,eShopOnAbp 就会被重命名到新的输出目录中。

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
public class RenameProgram
{
protected string InPath { get; set; }
protected string OutPath { get; set; }
protected string CompanyName { get; set; }
protected string ProjectName { get; set; }
protected string FullName { get; set; }

//此处未包含md文件
private static readonly string _includeFiles = ".original,.yml,.yaml,.cs,.cshtml,.js,.ts,.csproj,.sln,.xml,.config,.dotsettings,.json,.txt,.html,.gitignore,.ps1,.xaml,.plist,.local,.tpl,dockerfile";

public RenameProgram(string inPath, string outPath, string projectName, string companyName = null)
{
InPath = inPath;
OutPath = outPath;
ProjectName = projectName;
CompanyName = companyName;
FullName = string.Format("{1}{0}", projectName, !string.IsNullOrWhiteSpace(companyName) ? companyName + "." : "");
}

/// <summary>
/// 是否跳过
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
private bool isSkip(string file)
{
if (string.IsNullOrWhiteSpace(file)) return true;
var skipFiles = _includeFiles.Split(',');
return !skipFiles.Contains(file.ToLower());
}

/// <summary>
/// 替换名称
/// </summary>
/// <param name="data"></param>
/// <param name="extension"></param>
/// <returns></returns>
private string replaceData(string data, string extension = null)
{
if (string.IsNullOrWhiteSpace(data)) return data;
data = data.Replace(InPath, OutPath);
data = data.Replace("EShopOnAbp.", FullName + ".", StringComparison.Ordinal);
data = data.Replace("namespace EShopOnAbp", "namespace " + FullName, StringComparison.Ordinal);
data = data.Replace("EShopOnAbp", ProjectName, StringComparison.Ordinal);

if (!string.IsNullOrWhiteSpace(extension) && extension == ".js")
{
var tempName = ProjectName.Substring(0, 1).ToLower() + ProjectName.Substring(1);
data = data.Replace("eShopOnAbp", tempName, StringComparison.Ordinal);//js only
}
else
{
data = data.Replace("eShopOnAbp", ProjectName, StringComparison.Ordinal);
}

data = data.Replace("eshoponabp.", FullName.ToLower() + ".", StringComparison.Ordinal);
data = data.Replace("eshoponabp", ProjectName.ToLower(), StringComparison.Ordinal);
return data;
}

/// <summary>
/// 重命名
/// </summary>
/// <param name="path"></param>
private void Rename(string path)
{
var outputPath = replaceData(path);
if (!Directory.Exists(outputPath))
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("find: " + outputPath);
Directory.CreateDirectory(outputPath);
}

var files = Directory.GetFiles(path);
foreach (var file in files)
{
var fileInfo = new FileInfo(file);
var outputFile = replaceData(file);
var data = File.ReadAllText(file);
var extension = string.IsNullOrWhiteSpace(fileInfo.Extension) ? fileInfo.Name : fileInfo.Extension;
if (string.IsNullOrWhiteSpace(data) || !data.Contains("EShopOnAbp", StringComparison.OrdinalIgnoreCase) || isSkip(extension))
{
File.Copy(file, outputFile);
}
else
{
var outputData = replaceData(data, extension);
File.WriteAllText(outputFile, outputData);
}
}

var directories = Directory.GetDirectories(path);
foreach (var directory in directories)
{
if (directory.EndsWith(".git") || directory.EndsWith(".vs") || directory.EndsWith("bin") || directory.EndsWith("obj") || directory.EndsWith("node_modules"))
{
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine("skip: " + directory);
continue;
}
Rename(directory);
}
}

/// <summary>
/// 重命名
/// </summary>
public void Rename()
{
Rename(InPath);
}
}
文章作者: Ender
文章链接: https://www.fengyeju.net/archives/eshoponabp-rename-tool
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 枫叶居