comparison Tools/BLTgen/Program.cs @ 0:f990fcb411a9

Копия текущей версии из github
author cin
date Thu, 27 Mar 2014 21:46:09 +0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:f990fcb411a9
1 using System;
2 using System.ComponentModel;
3 using System.IO;
4 using System.Reflection;
5 using System.Text.RegularExpressions;
6
7 using BLToolkit.Mapping;
8 using BLToolkit.Reflection;
9 using BLToolkit.TypeBuilder;
10
11 namespace BLTgen
12 {
13 public class Arguments
14 {
15 [MapField(""), Description("source assembly location")]
16 public string SourceAssembly;
17
18 [MapField("B"), Description("Base type names to include (default: none). Example: /B:*EntityBase;SomeNamespace.*Base")]
19 public string BaseTypes;
20
21 [MapField("O"), Description("Output directory name (default: target assembly location). Example: /O:C:\\Temp")]
22 public string OutputDirectory;
23
24 [MapField("I"), Description("Type names to include (default: all). Example: /I:*Accessor;SomeNamespace.*;OtherNamespace.*")]
25 public string Include;
26
27 [MapField("X"), Description("Type names to exclude (default: none). Example: /X:SomeNamespace.SomeType")]
28 public string Exclude;
29
30 [MapField("K"), Description("The key pair that is used to create a strong name signature for the output assembly (default: none). Example: /K:C:\\SomePath\\key.snk")]
31 public string KeyPairFile;
32
33 [MapField("V"), Description("The version of the output assembly (same as source assembly by default). Example: /V:1.2.3.4")]
34 public string Version;
35
36 [MapField("D"), Description("Detailed output (default: false). Example: /D")]
37 public string Debug;
38 }
39
40 class Program
41 {
42 public static void Main(string[] args)
43 {
44 var parsedArgs = new Arguments();
45
46 Map.MapSourceToDestination(new StringListMapper(args), args,
47 Map.GetObjectMapper(typeof(Arguments)), parsedArgs);
48
49 WriteBanner();
50
51 if (string.IsNullOrEmpty(parsedArgs.SourceAssembly))
52 Usage();
53 else
54 GenerateExtensionAssembly(parsedArgs);
55 }
56
57 private static void GenerateExtensionAssembly(Arguments parsedArgs)
58 {
59 var verbose = parsedArgs.Debug != null;
60 var sourceAsm = Assembly.LoadFrom(parsedArgs.SourceAssembly);
61 var extensionAssemblyPath = GetOutputAssemblyLocation(sourceAsm.Location, parsedArgs.OutputDirectory);
62 var extensionAssemblyVersion = parsedArgs.Version != null? new Version(parsedArgs.Version): sourceAsm.GetName().Version;
63 var extensionAssemblyFolder = Path.GetDirectoryName(extensionAssemblyPath);
64
65 if (verbose)
66 Console.WriteLine("{0} =>{1}{2}", sourceAsm.Location, Environment.NewLine, extensionAssemblyPath);
67
68 if (!string.IsNullOrEmpty(extensionAssemblyFolder) && !Directory.Exists(extensionAssemblyFolder))
69 Directory.CreateDirectory(extensionAssemblyFolder);
70
71 var typesToProcess = sourceAsm.GetExportedTypes();
72
73 typesToProcess = FilterBaseTypes(typesToProcess, parsedArgs.BaseTypes);
74 typesToProcess = FilterTypes(typesToProcess, parsedArgs.Include, true);
75 typesToProcess = FilterTypes(typesToProcess, parsedArgs.Exclude, false);
76
77 if (typesToProcess.Length > 0)
78 {
79 AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs args)
80 {
81 foreach (var asm in ((AppDomain)sender).GetAssemblies())
82 {
83 if (string.Compare(asm.FullName, args.Name) == 0)
84 return asm;
85 }
86
87 return null;
88 };
89
90 TypeFactory.SaveTypes = true;
91 TypeFactory.SetGlobalAssembly(extensionAssemblyPath, extensionAssemblyVersion, parsedArgs.KeyPairFile);
92
93 foreach (var t in typesToProcess)
94 {
95 if (verbose)
96 Console.Write(GetFullTypeName(t));
97
98 // We cannot create accessors for generic definitions
99 //
100 if (t.IsGenericTypeDefinition)
101 {
102 if (verbose)
103 Console.WriteLine(" - skipping. Generic Definition");
104
105 continue;
106 }
107
108 if (verbose)
109 Console.WriteLine();
110
111 try
112 {
113 TypeAccessor.GetAccessor(t);
114 }
115 catch (Exception e)
116 {
117 if (verbose)
118 Console.WriteLine(e);
119 }
120 }
121
122 TypeFactory.SaveGlobalAssembly();
123 }
124 else if (verbose)
125 Console.WriteLine("No types to process.");
126 }
127
128 private static Type[] FilterBaseTypes(Type[] types, string pattern)
129 {
130 if (string.IsNullOrEmpty(pattern))
131 return types;
132
133 var re = new Regex("^" + Regex.Escape(pattern).Replace("\\*", ".*").Replace(";", "$|") + "$");
134
135 return Array.FindAll(types, delegate(Type t)
136 {
137 for (var bt = t.BaseType; bt != null; bt = bt.BaseType)
138 {
139 if (re.Match(GetFullTypeName(bt)).Success)
140 return true;
141 }
142 return false;
143 });
144 }
145
146 private static Type[] FilterTypes(Type[] types, string pattern, bool include)
147 {
148 if (string.IsNullOrEmpty(pattern))
149 return types;
150
151 var re = new Regex("^" + Regex.Escape(pattern).Replace("\\*", ".*").Replace(";", "$|") + "$");
152
153 return Array.FindAll(types, t => re.Match(GetFullTypeName(t)).Success == include);
154 }
155
156 // System.Type.FullName may be null under some conditions. See
157 // http://blogs.msdn.com/haibo_luo/archive/2006/02/17/534480.aspx
158 //
159 private static string GetFullTypeName(Type t)
160 {
161 var fullName = t.FullName;
162
163 if (fullName != null)
164 return fullName;
165
166 if (t.DeclaringType != null)
167 return GetFullTypeName(t.DeclaringType) + "+" + t.Name;
168
169 fullName = t.Namespace;
170 if (fullName != null)
171 fullName += ".";
172
173 fullName += t.Name;
174
175 return fullName;
176 }
177
178 private static string GetOutputAssemblyLocation(string sourceAssembly, string outputDirectory)
179 {
180 if (string.IsNullOrEmpty(outputDirectory))
181 outputDirectory = Path.GetDirectoryName(sourceAssembly);
182
183 var fileName = Path.ChangeExtension(Path.GetFileName(sourceAssembly), "BLToolkitExtension.dll");
184 return Path.Combine(Path.GetFullPath(outputDirectory), fileName);
185 }
186
187 #region Usage
188
189 private static void WriteBanner()
190 {
191 var asm = Assembly.GetExecutingAssembly();
192 var descriptionAttribute = (AssemblyDescriptionAttribute)
193 Attribute.GetCustomAttribute(asm, typeof (AssemblyDescriptionAttribute));
194 var copyrightAttribute = (AssemblyCopyrightAttribute)
195 Attribute.GetCustomAttribute(asm, typeof(AssemblyCopyrightAttribute));
196
197 Console.WriteLine("{0}, Version {1}", descriptionAttribute.Description, asm.GetName().Version);
198 Console.WriteLine(copyrightAttribute.Copyright);
199 Console.WriteLine();
200 }
201
202 private static string ExecutableName
203 {
204 get { return Path.GetFileName(new Uri(Assembly.GetEntryAssembly().EscapedCodeBase).LocalPath); }
205 }
206
207 private static string GetDescription(MemberMapper mm)
208 {
209 var desc = mm.MemberAccessor.GetAttribute<DescriptionAttribute>();
210
211 return (null != desc) ? desc.Description : string.Empty;
212 }
213
214 private static void Usage()
215 {
216 var om = Map.GetObjectMapper(typeof(Arguments));
217
218 Console.Write("Usage: {0}", ExecutableName);
219
220 foreach (MemberMapper mm in om)
221 {
222 if (0 == mm.Name.Length)
223 Console.Write(" <{0}>", GetDescription(mm));
224 else
225 Console.Write(" /{0}:", mm.Name);
226 }
227
228 Console.WriteLine();
229 Console.WriteLine("Options:");
230
231 foreach (MemberMapper mm in om)
232 {
233 if (0 != mm.Name.Length)
234 Console.WriteLine("\t{0}: {1}", mm.Name, GetDescription(mm));
235 }
236
237 Console.WriteLine();
238 }
239
240 #endregion
241 }
242 }