1
- <#@ template language="C#" hostspecific="True" #>
1
+ <#@ template language="C#" hostspecific="True" #>
2
2
<#@ assembly name="EnvDTE" #>
3
3
<#@ assembly name="System.Core.dll" #>
4
4
<#@ assembly name="System.Data" #>
17
17
<#@ import namespace="System.Text.RegularExpressions" #>
18
18
<#@ import namespace="System.Configuration" #>
19
19
<#@ import namespace="System.Windows.Forms" #>
20
+ <#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>
20
21
<#+
21
22
22
23
/*
81
82
82
83
string ConnectionStringName = "";
83
84
string Namespace = "";
84
- string RepoName = "";
85
85
string ClassPrefix = "";
86
86
string ClassSuffix = "";
87
87
string SchemaName = null;
@@ -2362,4 +2362,178 @@ public static class Inflector {
2362
2362
#endregion
2363
2363
}
2364
2364
2365
- #>
2365
+ /*
2366
+ Manager.tt from Damien Guard: http://damieng.com/blog/2009/11/06/multiple-outputs-from-t4-made-easy-revisited
2367
+ */
2368
+
2369
+
2370
+ // Manager class records the various blocks so it can split them up
2371
+ class Manager {
2372
+ private class Block {
2373
+ public String Name;
2374
+ public int Start, Length;
2375
+ }
2376
+
2377
+ private Block currentBlock;
2378
+ private List<Block> files = new List<Block>();
2379
+ private Block footer = new Block();
2380
+ private Block header = new Block();
2381
+ private ITextTemplatingEngineHost host;
2382
+ private StringBuilder template;
2383
+ protected List<String> generatedFileNames = new List<String>();
2384
+
2385
+ public static Manager Create(ITextTemplatingEngineHost host, StringBuilder template) {
2386
+ return (host is IServiceProvider) ? new VSManager(host, template) : new Manager(host, template);
2387
+ }
2388
+
2389
+ public void KeepGeneratedFile(String name) {
2390
+ name = Path.Combine(Path.GetDirectoryName(host.TemplateFile), name);
2391
+ generatedFileNames.Add(name);
2392
+ }
2393
+
2394
+ public void StartNewFile(String name) {
2395
+ if (name == null)
2396
+ throw new ArgumentNullException("name");
2397
+ CurrentBlock = new Block { Name = name };
2398
+ }
2399
+
2400
+ public void StartFooter() {
2401
+ CurrentBlock = footer;
2402
+ }
2403
+
2404
+ public void StartHeader() {
2405
+ CurrentBlock = header;
2406
+ }
2407
+
2408
+ public void EndBlock() {
2409
+ if (CurrentBlock == null)
2410
+ return;
2411
+ CurrentBlock.Length = template.Length - CurrentBlock.Start;
2412
+ if (CurrentBlock != header && CurrentBlock != footer)
2413
+ files.Add(CurrentBlock);
2414
+ currentBlock = null;
2415
+ }
2416
+
2417
+ public virtual void Process(bool split) {
2418
+ if (split) {
2419
+ EndBlock();
2420
+ String headerText = template.ToString(header.Start, header.Length);
2421
+ String footerText = template.ToString(footer.Start, footer.Length);
2422
+ String outputPath = Path.GetDirectoryName(host.TemplateFile);
2423
+ files.Reverse();
2424
+ foreach (Block block in files) {
2425
+ String fileName = Path.Combine(outputPath, block.Name);
2426
+ String content = headerText + template.ToString(block.Start, block.Length) + footerText;
2427
+ generatedFileNames.Add(fileName);
2428
+ CreateFile(fileName, content);
2429
+ template.Remove(block.Start, block.Length);
2430
+ }
2431
+ }
2432
+ }
2433
+
2434
+ protected virtual void CreateFile(String fileName, String content) {
2435
+ if (IsFileContentDifferent(fileName, content))
2436
+ File.WriteAllText(fileName, content);
2437
+ }
2438
+
2439
+ public virtual String GetCustomToolNamespace(String fileName) {
2440
+ return null;
2441
+ }
2442
+
2443
+ public virtual String DefaultProjectNamespace {
2444
+ get { return null; }
2445
+ }
2446
+
2447
+ protected bool IsFileContentDifferent(String fileName, String newContent) {
2448
+ return !(File.Exists(fileName) && File.ReadAllText(fileName) == newContent);
2449
+ }
2450
+
2451
+ private Manager(ITextTemplatingEngineHost host, StringBuilder template) {
2452
+ this.host = host;
2453
+ this.template = template;
2454
+ }
2455
+
2456
+ private Block CurrentBlock {
2457
+ get { return currentBlock; }
2458
+ set {
2459
+ if (CurrentBlock != null)
2460
+ EndBlock();
2461
+ if (value != null)
2462
+ value.Start = template.Length;
2463
+ currentBlock = value;
2464
+ }
2465
+ }
2466
+
2467
+ private class VSManager : Manager {
2468
+ private EnvDTE.ProjectItem templateProjectItem;
2469
+ private EnvDTE.DTE dte;
2470
+ private Action<String> checkOutAction;
2471
+ private Action<IEnumerable<String>> projectSyncAction;
2472
+
2473
+ public override String DefaultProjectNamespace {
2474
+ get {
2475
+ return templateProjectItem.ContainingProject.Properties.Item("DefaultNamespace").Value.ToString();
2476
+ }
2477
+ }
2478
+
2479
+ public override String GetCustomToolNamespace(string fileName) {
2480
+ return dte.Solution.FindProjectItem(fileName).Properties.Item("CustomToolNamespace").Value.ToString();
2481
+ }
2482
+
2483
+ public override void Process(bool split) {
2484
+ if (templateProjectItem.ProjectItems == null)
2485
+ return;
2486
+ base.Process(split);
2487
+ projectSyncAction.EndInvoke(projectSyncAction.BeginInvoke(generatedFileNames, null, null));
2488
+ }
2489
+
2490
+ protected override void CreateFile(String fileName, String content) {
2491
+ if (IsFileContentDifferent(fileName, content)) {
2492
+ CheckoutFileIfRequired(fileName);
2493
+ File.WriteAllText(fileName, content);
2494
+ }
2495
+ }
2496
+
2497
+ internal VSManager(ITextTemplatingEngineHost host, StringBuilder template)
2498
+ : base(host, template) {
2499
+ var hostServiceProvider = (IServiceProvider)host;
2500
+ if (hostServiceProvider == null)
2501
+ throw new ArgumentNullException("Could not obtain IServiceProvider");
2502
+ dte = (EnvDTE.DTE)hostServiceProvider.GetService(typeof(EnvDTE.DTE));
2503
+ if (dte == null)
2504
+ throw new ArgumentNullException("Could not obtain DTE from host");
2505
+ templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile);
2506
+ checkOutAction = (String fileName) => dte.SourceControl.CheckOutItem(fileName);
2507
+ projectSyncAction = (IEnumerable<String> keepFileNames) => ProjectSync(templateProjectItem, keepFileNames);
2508
+ }
2509
+
2510
+ private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, IEnumerable<String> keepFileNames) {
2511
+ var keepFileNameSet = new HashSet<String>(keepFileNames);
2512
+ var projectFiles = new Dictionary<String, EnvDTE.ProjectItem>();
2513
+ var originalFilePrefix = Path.GetFileNameWithoutExtension(templateProjectItem.get_FileNames(0)) + ".";
2514
+ foreach (EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems)
2515
+ projectFiles.Add(projectItem.get_FileNames(0), projectItem);
2516
+
2517
+ // Remove unused items from the project
2518
+ foreach (var pair in projectFiles)
2519
+ if (!keepFileNames.Contains(pair.Key) && !(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalFilePrefix))
2520
+ pair.Value.Delete();
2521
+
2522
+ // Add missing files to the project
2523
+ foreach (String fileName in keepFileNameSet)
2524
+ if (!projectFiles.ContainsKey(fileName))
2525
+ templateProjectItem.ProjectItems.AddFromFile(fileName);
2526
+ }
2527
+
2528
+ private void CheckoutFileIfRequired(String fileName) {
2529
+ var sc = dte.SourceControl;
2530
+ if (sc != null && sc.IsItemUnderSCC(fileName) && !sc.IsItemCheckedOut(fileName))
2531
+ checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null));
2532
+ }
2533
+ }
2534
+ }
2535
+
2536
+ /*
2537
+ End of Manager.tt
2538
+ */
2539
+ #>
0 commit comments