With Visual Studio comes the T4 code generator, and I have been reading about it today. While reading online and trying it out, I created a resource helper template. What this template does is scan the current folder for all resource files and creates a static helper class to allow easy access to the resource variables without having to update code for the resource manually every time.
This is not a standard feature of Visual Studio, but you can download T4 Editor and T4 Toolbox to assist with templates and syntax highlighting.
Starting off, you will need to create a project and add the resource files. Then you need to add a text file, renaming it, to "ResourceGenerator.tt". The .tt extension lets the IDE know this is a custom generator file.
The first line of the file will consist of
1: <#@ template language="C#" HostSpecific="True" #>
HostSpecific="True" as explained on MSDN: "If you set the value of this parameter to true, you can access a property called Host in your text template." We will be using Host to retrieve the current project folder.
Then comes the normal C# using directives, with a slight difference.
1: <#@ import namespace="System.IO"#>
2: <#@ import namespace="System.Text"#>
3: <#@ import namespace="System.Text.RegularExpressions"#>
Next we start with the code
1: <#
2: string baseDir = Host.ResolvePath("");
3: CreateResourceManagers(baseDir);
4: #>
<# and #> specifies code blocks
Then the bulk of the code to complete this demo.
1: <#+
2: public static void CreateResourceManagers(string dirPath)
3: {
4: DirectoryInfo directoryInfo = new DirectoryInfo(dirPath);
5:
6: foreach(FileInfo file in directoryInfo.GetFiles("*.designer.cs"))
7: {
8: string resource = string.Empty;
9: StringBuilder sb = new StringBuilder();
10: using(StreamReader reader = new StreamReader(file.FullName))
11: {
12: resource = reader.ReadToEnd();
13: }
14:
15: Regex pattern = new Regex(@"internal class (?<className>S*)");
16:
17: Match match = pattern.Match(resource);
18:
19: string className = match.Groups["className"].Value;
20: string fileName = className + "Helper.cs";
21:
22: sb.AppendLine("using System.Threading;");
23: sb.AppendLine("using System.Globalization;");
24: sb.AppendLine();
25: sb.AppendLine("namespace T4Demo.Resources");
26: sb.AppendLine("{");
27: sb.AppendLine("public static class " + className + "Helper");
28: sb.AppendLine("{");
29: sb.AppendLine("private static readonly CultureInfo ResourceCulture;");
30: sb.AppendLine();
31: sb.AppendLine("static " + className + "Helper()");
32: sb.AppendLine("{");
33: sb.AppendLine("ResourceCulture = Thread.CurrentThread.CurrentCulture;");
34: sb.AppendLine("}");
35:
36: pattern = new Regex(@"internal static string (?<property>S*).*[{]");
37:
38: match = pattern.Match(resource);
39:
40: if(match.Success)
41: {
42: do
43: {
44: string property = match.Groups["property"].Value;
45: sb.AppendLine();
46:
47: sb.AppendLine("public static string " + property);
48: sb.AppendLine("{");
49: sb.AppendLine("get");
50: sb.AppendLine("{");
51: sb.AppendLine("" + className + ".Culture = ResourceCulture;");
52: sb.AppendLine("return " + className + "." + property + ";");
53: sb.AppendLine("}");
54: sb.AppendLine("}");
55:
56:
57: match = match.NextMatch();
58: } while (match.Success);
59: }
60:
61: sb.AppendLine("}");
62: sb.AppendLine("}");
63:
64:
65: using(StreamWriter wr = new StreamWriter(dirPath + @"" + fileName))
66: {
67: wr.Write(sb.ToString());
68: }
69: }
70: }
71: #>
The <#+ on line 1 says to the code generator that a C# block of code will follow. The code in this block is standard C#.
**Something that I found to help a lot. Code as far as you can in a C# class and then move it to the .tt file. Intellisense and syntax highlighting is a big help.
Reference used: http://www.olegsych.com
Click here to download the template