[{"data":1,"prerenderedAt":1871},["ShallowReactive",2],{"blog:2009:multiple-outputs-from-t4-made-easy":3,"blogMore-Development":1857,"comments-multiple-outputs-from-t4-made-easy":1870},{"id":4,"title":5,"body":6,"category":1839,"commentCount":413,"date":1840,"description":1841,"excerpt":1842,"extension":1843,"filenames":1844,"hidden":1845,"image":1844,"meta":1846,"minutes":239,"navigation":235,"path":1847,"seo":1848,"showCategory":1844,"stem":1849,"tags":1850,"updated":1844,"url":1854,"wordCount":1855,"__hash__":1856},"content\u002Fblog\u002F2009\u002Fmultiple-outputs-from-t4-made-easy.md","Multiple outputs from T4 made easy",{"type":7,"value":8,"toc":1830},"minimark",[9,21,31,36,41,44,118,122,125,187,191,194,251,255,258,281,286,290,293,307,1820,1826],[10,11,12],"blockquote",{},[13,14,15,16],"p",{},"An ",[17,18,20],"a",{"href":19},"\u002Fblog\u002F2009\u002Fmultiple-outputs-from-t4-made-easy-revisited\u002F","improved version is now available.",[13,22,23,24,30],{},"One of the things I wanted my ",[17,25,29],{"href":26,"rel":27},"https:\u002F\u002Fl2st4.codeplex.com",[28],"nofollow","LINQ to SQL T4 templates"," to do was be able to split the output into a file-per-entity. Existing solutions used either a separate set of templates with duplicate code or intrusive handling code throughout the template. Here’s my helper class to abstract the problem away from what is already complicated enough template code.",[32,33,35],"h2",{"id":34},"using-the-manager-class","Using the Manager class",[37,38,40],"h3",{"id":39},"setup","Setup",[13,42,43],{},"You’ll need to get the code into your template, either by copying the code in or referencing it with an include directive. Then declare an instance of the Manager class passing in some environmental options such as the desired default output path.",[45,46,51],"pre",{"className":47,"code":48,"language":49,"meta":50,"style":50},"language-csharp shiki shiki-themes everforest-light dracula","\u003C#@ template language=\"C#v3.5\" hostspecific=\"True\"\n#>\u003C#@ include file=\"Manager.ttinclude\"\n#>\u003C# var manager = new Manager(Host, GenerationEnvironment, true) { OutputPath = Path.GetDirectoryName(Host.TemplateFile) }; #>\n","csharp","",[52,53,54,100,110],"code",{"__ignoreMap":50},[55,56,59,63,67,71,74,77,81,85,87,90,92,94,97],"span",{"class":57,"line":58},"line",1,[55,60,62],{"class":61},"s9HRq","\u003C",[55,64,66],{"class":65},"s6Vpi","#@ ",[55,68,70],{"class":69},"snuxY","template",[55,72,73],{"class":65}," language",[55,75,76],{"class":61},"=",[55,78,80],{"class":79},"sciFF","\"",[55,82,84],{"class":83},"sJQOs","C#v3.5",[55,86,80],{"class":79},[55,88,89],{"class":65}," hostspecific",[55,91,76],{"class":61},[55,93,80],{"class":79},[55,95,96],{"class":83},"True",[55,98,99],{"class":79},"\"\n",[55,101,103,107],{"class":57,"line":102},2,[55,104,106],{"class":105},"sZQI_","#",[55,108,109],{"class":65},">\u003C#@ include file=\"Manager.ttinclude\"\n",[55,111,113,115],{"class":57,"line":112},3,[55,114,106],{"class":105},[55,116,117],{"class":65},">\u003C# var manager = new Manager(Host, GenerationEnvironment, true) { OutputPath = Path.GetDirectoryName(Host.TemplateFile) }; #>\n",[37,119,121],{"id":120},"define-a-block","Define a block",[13,123,124],{},"Then add one line before and one line after each block which could be split out into it’s own file passing in what the filename would be if split.",[45,126,128],{"className":47,"code":127,"language":49,"meta":50,"style":50},"\u003C# manager.StartBlock(\"Employee.generated.cs\"); #>\npublic class Employee { … }\n\u003C# manager.EndBlock(); #>\n",[52,129,130,157,173],{"__ignoreMap":50},[55,131,132,134,137,141,144,146,149,151,154],{"class":57,"line":58},[55,133,62],{"class":61},[55,135,136],{"class":65},"# manager.",[55,138,140],{"class":139},"sS4Kt","StartBlock",[55,142,143],{"class":65},"(",[55,145,80],{"class":79},[55,147,148],{"class":83},"Employee.generated.cs",[55,150,80],{"class":79},[55,152,153],{"class":65},"); #",[55,155,156],{"class":61},">\n",[55,158,159,162,166,170],{"class":57,"line":102},[55,160,161],{"class":61},"public",[55,163,165],{"class":164},"smiwp"," class",[55,167,169],{"class":168},"sPLAf"," Employee",[55,171,172],{"class":65}," { … }\n",[55,174,175,177,179,182,185],{"class":57,"line":112},[55,176,62],{"class":61},[55,178,136],{"class":65},[55,180,181],{"class":139},"EndBlock",[55,183,184],{"class":65},"(); #",[55,186,156],{"class":61},[37,188,190],{"id":189},"headers-and-footers","Headers and footers",[13,192,193],{},"Many templates need to share a common header\u002Ffooter for such things as comments or using\u002Fimport statements or turning on\u002Foff warnings. Simply use StartHeader\u002FEndHeader and StartFooter\u002FEndFooter. The resulting blocks will be emitted into all split files and left in the original output too.",[45,195,197],{"className":47,"code":196,"language":49,"meta":50,"style":50},"\u003C# manager.StartHeader(); #>\n\u002F\u002F Code generated template\nusing System;\n\n\u003C# manager.EndHeader(); #>\n",[52,198,199,212,218,230,237],{"__ignoreMap":50},[55,200,201,203,205,208,210],{"class":57,"line":58},[55,202,62],{"class":61},[55,204,136],{"class":65},[55,206,207],{"class":139},"StartHeader",[55,209,184],{"class":65},[55,211,156],{"class":61},[55,213,214],{"class":57,"line":102},[55,215,217],{"class":216},"sSX4p","\u002F\u002F Code generated template\n",[55,219,220,223,227],{"class":57,"line":112},[55,221,222],{"class":164},"using",[55,224,226],{"class":225},"sjYfO"," System",[55,228,229],{"class":65},";\n",[55,231,233],{"class":57,"line":232},4,[55,234,236],{"emptyLinePlaceholder":235},true,"\n",[55,238,240,242,244,247,249],{"class":57,"line":239},5,[55,241,62],{"class":61},[55,243,136],{"class":65},[55,245,246],{"class":139},"EndHeader",[55,248,184],{"class":65},[55,250,156],{"class":61},[37,252,254],{"id":253},"process","Process",[13,256,257],{},"At the end of the template call Process to handle splitting the files (true) or not (false). Anything not included in a specific start\u002Fend block will remain in the original output file.",[45,259,261],{"className":47,"code":260,"language":49,"meta":50,"style":50},"\u003C# manager.Process(true); #>\n",[52,262,263],{"__ignoreMap":50},[55,264,265,267,269,271,273,277,279],{"class":57,"line":58},[55,266,62],{"class":61},[55,268,136],{"class":65},[55,270,254],{"class":139},[55,272,143],{"class":65},[55,274,276],{"class":275},"s3Ipq","true",[55,278,153],{"class":65},[55,280,156],{"class":61},[10,282,283],{},[13,284,285],{},"When processing each block name in the Output path will either be overwritten or deleted to enable proper clean-up. It will also add and remove the files from Visual Studio so make sure your generated names aren’t going to collide with hand-written ones!",[32,287,289],{"id":288},"manager-classes","Manager classes",[13,291,292],{},"Here is the Manger class itself as well as the small ManagementStrategy classes that determines what to do with the files within Visual Studio (add\u002Fremove project items) and outside of Visual Studio (create\u002Fdelete files).",[10,294,295],{},[13,296,297,298,302,303],{},"Download ",[17,299,301],{"href":300},"https:\u002F\u002Fdl.damieng.com\u002Fdotnet\u002FManager.ttinclude","Manager.ttinclude"," (4KB)\nLicensed under the ",[17,304,306],{"href":305},"https:\u002F\u002Fwww.microsoft.com\u002Fopensource\u002Flicenses.mspx","Microsoft Public License (MS-PL)",[45,308,310],{"className":47,"code":309,"language":49,"meta":50,"style":50},"\u003C#@ assembly name=\"System.Core\"\n#>\u003C#@ assembly name=\"EnvDTE\"\n#>\u003C#@ import namespace=\"System.Collections.Generic\"\n#>\u003C#@ import namespace=\"System.IO\"\n#>\u003C#@ import namespace=\"System.Text\"\n#>\u003C#@ import namespace=\"Microsoft.VisualStudio.TextTemplating\"\n#>\u003C#+\n\n\u002F\u002F T4 Template Block manager for handling multiple file outputs more easily.\n\u002F\u002F Copyright (c) Microsoft Corporation.  All rights reserved.\n\u002F\u002F This source code is made available under the terms of the Microsoft Public License (MS-PL)\n\n\u002F\u002F Manager class records the various blocks so it can split them up\nclass Manager\n{\n    private struct Block {\n        public String Name;\n        public int Start, Length;\n    }\n\n    private List\u003CBlock> blocks = new List\u003CBlock>();\n    private Block currentBlock;\n    private Block footerBlock = new Block();\n    private Block headerBlock = new Block();\n    private ITextTemplatingEngineHost host;\n    private ManagementStrategy strategy;\n    private StringBuilder template;\n    public String OutputPath { get; set; }\n\n    public Manager(ITextTemplatingEngineHost host, StringBuilder template, bool commonHeader) {\n        this.host = host;\n        this.template = template;\n        OutputPath = String.Empty;\n        strategy = ManagementStrategy.Create(host);\n    }\n\n    public void StartBlock(String name) {\n        currentBlock = new Block { Name = name, Start = template.Length };\n    }\n\n    public void StartFooter() {\n        footerBlock.Start = template.Length;\n    }\n\n    public void EndFooter() {\n        footerBlock.Length = template.Length - footerBlock.Start;\n    }\n\n    public void StartHeader() {\n        headerBlock.Start = template.Length;\n    }\n\n    public void EndHeader() {\n        headerBlock.Length = template.Length - headerBlock.Start;\n    }\n\n    public void EndBlock() {\n        currentBlock.Length = template.Length - currentBlock.Start;\n        blocks.Add(currentBlock);\n    }\n\n    public void Process(bool split) {\n        String header = template.ToString(headerBlock.Start, headerBlock.Length);\n        String footer = template.ToString(footerBlock.Start, footerBlock.Length);\n        blocks.Reverse();\n        foreach(Block block in blocks) {\n            String fileName = Path.Combine(OutputPath, block.Name);\n            if (split) {\n                String content = header + template.ToString(block.Start, block.Length) + footer;\n                strategy.CreateFile(fileName, content);\n                template.Remove(block.Start, block.Length);\n            } else {\n                strategy.DeleteFile(fileName);\n            }\n        }\n    }\n}\n\nclass ManagementStrategy\n{\n    internal static ManagementStrategy Create(ITextTemplatingEngineHost host) {\n        return (host is IServiceProvider) ? new VSManagementStrategy(host) : new ManagementStrategy(host);\n    }\n\n    internal ManagementStrategy(ITextTemplatingEngineHost host) { }\n\n    internal virtual void CreateFile(String fileName, String content) {\n        File.WriteAllText(fileName, content);\n    }\n\n    internal virtual void DeleteFile(String fileName) {\n        if (File.Exists(fileName))\n            File.Delete(fileName);\n    }\n}\n\nclass VSManagementStrategy : ManagementStrategy\n{\n    private EnvDTE.ProjectItem templateProjectItem;\n\n    internal VSManagementStrategy(ITextTemplatingEngineHost host) : base(host) {\n        IServiceProvider hostServiceProvider = (IServiceProvider)host;\n        if (hostServiceProvider == null)\n            throw new ArgumentNullException(\"Could not obtain hostServiceProvider\");\n\n        EnvDTE.DTE dte = (EnvDTE.DTE)hostServiceProvider.GetService(typeof(EnvDTE.DTE));\n        if (dte == null)\n            throw new ArgumentNullException(\"Could not obtain DTE from host\");\n\n        templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile);\n    }\n\n    internal override void CreateFile(String fileName, String content) {\n        base.CreateFile(fileName, content);\n        ((EventHandler)delegate { templateProjectItem.ProjectItems.AddFromFile(fileName); }).BeginInvoke(null, null, null, null);\n    }\n\n    internal override void DeleteFile(String fileName) {\n        ((EventHandler)delegate { FindAndDeleteFile(fileName); }).BeginInvoke(null, null, null, null);\n    }\n\n    private void FindAndDeleteFile(String fileName) {\n        foreach(EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems) {\n            if (projectItem.get_FileNames(0) == fileName) {\n                projectItem.Delete();\n                return;\n            }\n        }\n    }\n}#>\n",[52,311,312,333,340,347,354,361,369,377,382,388,394,400,405,411,417,423,429,435,448,454,459,491,497,513,527,533,539,545,551,556,574,594,608,624,641,646,651,665,696,701,706,719,736,741,746,758,781,786,791,803,819,824,829,841,863,868,873,885,908,920,925,930,947,973,997,1007,1022,1044,1053,1089,1101,1120,1126,1137,1143,1149,1154,1160,1165,1171,1176,1187,1225,1230,1235,1247,1252,1266,1277,1282,1287,1300,1315,1326,1331,1336,1341,1352,1357,1369,1374,1394,1411,1428,1450,1455,1500,1514,1534,1539,1566,1571,1576,1588,1600,1652,1657,1662,1673,1712,1717,1722,1735,1758,1781,1791,1797,1802,1807,1812],{"__ignoreMap":50},[55,313,314,316,318,321,324,326,328,331],{"class":57,"line":58},[55,315,62],{"class":61},[55,317,66],{"class":65},[55,319,320],{"class":69},"assembly",[55,322,323],{"class":65}," name",[55,325,76],{"class":61},[55,327,80],{"class":79},[55,329,330],{"class":83},"System.Core",[55,332,99],{"class":79},[55,334,335,337],{"class":57,"line":102},[55,336,106],{"class":105},[55,338,339],{"class":65},">\u003C#@ assembly name=\"EnvDTE\"\n",[55,341,342,344],{"class":57,"line":112},[55,343,106],{"class":105},[55,345,346],{"class":65},">\u003C#@ import namespace=\"System.Collections.Generic\"\n",[55,348,349,351],{"class":57,"line":232},[55,350,106],{"class":105},[55,352,353],{"class":65},">\u003C#@ import namespace=\"System.IO\"\n",[55,355,356,358],{"class":57,"line":239},[55,357,106],{"class":105},[55,359,360],{"class":65},">\u003C#@ import namespace=\"System.Text\"\n",[55,362,364,366],{"class":57,"line":363},6,[55,365,106],{"class":105},[55,367,368],{"class":65},">\u003C#@ import namespace=\"Microsoft.VisualStudio.TextTemplating\"\n",[55,370,372,374],{"class":57,"line":371},7,[55,373,106],{"class":105},[55,375,376],{"class":65},">\u003C#+\n",[55,378,380],{"class":57,"line":379},8,[55,381,236],{"emptyLinePlaceholder":235},[55,383,385],{"class":57,"line":384},9,[55,386,387],{"class":216},"\u002F\u002F T4 Template Block manager for handling multiple file outputs more easily.\n",[55,389,391],{"class":57,"line":390},10,[55,392,393],{"class":216},"\u002F\u002F Copyright (c) Microsoft Corporation.  All rights reserved.\n",[55,395,397],{"class":57,"line":396},11,[55,398,399],{"class":216},"\u002F\u002F This source code is made available under the terms of the Microsoft Public License (MS-PL)\n",[55,401,403],{"class":57,"line":402},12,[55,404,236],{"emptyLinePlaceholder":235},[55,406,408],{"class":57,"line":407},13,[55,409,410],{"class":216},"\u002F\u002F Manager class records the various blocks so it can split them up\n",[55,412,414],{"class":57,"line":413},14,[55,415,416],{"class":65},"class Manager\n",[55,418,420],{"class":57,"line":419},15,[55,421,422],{"class":65},"{\n",[55,424,426],{"class":57,"line":425},16,[55,427,428],{"class":65},"    private struct Block {\n",[55,430,432],{"class":57,"line":431},17,[55,433,434],{"class":65},"        public String Name;\n",[55,436,438,441,445],{"class":57,"line":437},18,[55,439,440],{"class":65},"        public ",[55,442,444],{"class":443},"sXAHl","int",[55,446,447],{"class":65}," Start, Length;\n",[55,449,451],{"class":57,"line":450},19,[55,452,453],{"class":65},"    }\n",[55,455,457],{"class":57,"line":456},20,[55,458,236],{"emptyLinePlaceholder":235},[55,460,462,465,467,470,473,476,478,481,484,486,488],{"class":57,"line":461},21,[55,463,464],{"class":65},"    private List",[55,466,62],{"class":61},[55,468,469],{"class":65},"Block",[55,471,472],{"class":61},">",[55,474,475],{"class":65}," blocks ",[55,477,76],{"class":61},[55,479,480],{"class":164}," new",[55,482,483],{"class":69}," List",[55,485,62],{"class":65},[55,487,469],{"class":69},[55,489,490],{"class":65},">();\n",[55,492,494],{"class":57,"line":493},22,[55,495,496],{"class":65},"    private Block currentBlock;\n",[55,498,500,503,505,507,510],{"class":57,"line":499},23,[55,501,502],{"class":65},"    private Block footerBlock ",[55,504,76],{"class":61},[55,506,480],{"class":164},[55,508,509],{"class":69}," Block",[55,511,512],{"class":65},"();\n",[55,514,516,519,521,523,525],{"class":57,"line":515},24,[55,517,518],{"class":65},"    private Block headerBlock ",[55,520,76],{"class":61},[55,522,480],{"class":164},[55,524,509],{"class":69},[55,526,512],{"class":65},[55,528,530],{"class":57,"line":529},25,[55,531,532],{"class":65},"    private ITextTemplatingEngineHost host;\n",[55,534,536],{"class":57,"line":535},26,[55,537,538],{"class":65},"    private ManagementStrategy strategy;\n",[55,540,542],{"class":57,"line":541},27,[55,543,544],{"class":65},"    private StringBuilder template;\n",[55,546,548],{"class":57,"line":547},28,[55,549,550],{"class":65},"    public String OutputPath { get; set; }\n",[55,552,554],{"class":57,"line":553},29,[55,555,236],{"emptyLinePlaceholder":235},[55,557,559,562,565,568,571],{"class":57,"line":558},30,[55,560,561],{"class":65},"    public ",[55,563,564],{"class":139},"Manager",[55,566,567],{"class":65},"(ITextTemplatingEngineHost host, StringBuilder template, ",[55,569,570],{"class":443},"bool",[55,572,573],{"class":65}," commonHeader) {\n",[55,575,577,581,584,588,591],{"class":57,"line":576},31,[55,578,580],{"class":579},"sKO3f","        this",[55,582,583],{"class":65},".",[55,585,587],{"class":586},"sSKRk","host",[55,589,590],{"class":61}," =",[55,592,593],{"class":65}," host;\n",[55,595,597,599,601,603,605],{"class":57,"line":596},32,[55,598,580],{"class":579},[55,600,583],{"class":65},[55,602,70],{"class":586},[55,604,590],{"class":61},[55,606,607],{"class":65}," template;\n",[55,609,611,614,616,619,622],{"class":57,"line":610},33,[55,612,613],{"class":65},"        OutputPath ",[55,615,76],{"class":61},[55,617,618],{"class":65}," String.",[55,620,621],{"class":586},"Empty",[55,623,229],{"class":65},[55,625,627,630,632,635,638],{"class":57,"line":626},34,[55,628,629],{"class":65},"        strategy ",[55,631,76],{"class":61},[55,633,634],{"class":65}," ManagementStrategy.",[55,636,637],{"class":139},"Create",[55,639,640],{"class":65},"(host);\n",[55,642,644],{"class":57,"line":643},35,[55,645,453],{"class":65},[55,647,649],{"class":57,"line":648},36,[55,650,236],{"emptyLinePlaceholder":235},[55,652,654,656,659,662],{"class":57,"line":653},37,[55,655,561],{"class":65},[55,657,658],{"class":443},"void",[55,660,661],{"class":139}," StartBlock",[55,663,664],{"class":65},"(String name) {\n",[55,666,668,671,673,675,677,680,682,685,687,690,693],{"class":57,"line":667},38,[55,669,670],{"class":65},"        currentBlock ",[55,672,76],{"class":61},[55,674,480],{"class":164},[55,676,509],{"class":69},[55,678,679],{"class":65}," { Name ",[55,681,76],{"class":61},[55,683,684],{"class":65}," name, Start ",[55,686,76],{"class":61},[55,688,689],{"class":65}," template.",[55,691,692],{"class":586},"Length",[55,694,695],{"class":65}," };\n",[55,697,699],{"class":57,"line":698},39,[55,700,453],{"class":65},[55,702,704],{"class":57,"line":703},40,[55,705,236],{"emptyLinePlaceholder":235},[55,707,709,711,713,716],{"class":57,"line":708},41,[55,710,561],{"class":65},[55,712,658],{"class":443},[55,714,715],{"class":139}," StartFooter",[55,717,718],{"class":65},"() {\n",[55,720,722,725,728,730,732,734],{"class":57,"line":721},42,[55,723,724],{"class":65},"        footerBlock.",[55,726,727],{"class":586},"Start",[55,729,590],{"class":61},[55,731,689],{"class":65},[55,733,692],{"class":586},[55,735,229],{"class":65},[55,737,739],{"class":57,"line":738},43,[55,740,453],{"class":65},[55,742,744],{"class":57,"line":743},44,[55,745,236],{"emptyLinePlaceholder":235},[55,747,749,751,753,756],{"class":57,"line":748},45,[55,750,561],{"class":65},[55,752,658],{"class":443},[55,754,755],{"class":139}," EndFooter",[55,757,718],{"class":65},[55,759,761,763,765,767,769,771,774,777,779],{"class":57,"line":760},46,[55,762,724],{"class":65},[55,764,692],{"class":586},[55,766,590],{"class":61},[55,768,689],{"class":65},[55,770,692],{"class":586},[55,772,773],{"class":61}," -",[55,775,776],{"class":65}," footerBlock.",[55,778,727],{"class":586},[55,780,229],{"class":65},[55,782,784],{"class":57,"line":783},47,[55,785,453],{"class":65},[55,787,789],{"class":57,"line":788},48,[55,790,236],{"emptyLinePlaceholder":235},[55,792,794,796,798,801],{"class":57,"line":793},49,[55,795,561],{"class":65},[55,797,658],{"class":443},[55,799,800],{"class":139}," StartHeader",[55,802,718],{"class":65},[55,804,806,809,811,813,815,817],{"class":57,"line":805},50,[55,807,808],{"class":65},"        headerBlock.",[55,810,727],{"class":586},[55,812,590],{"class":61},[55,814,689],{"class":65},[55,816,692],{"class":586},[55,818,229],{"class":65},[55,820,822],{"class":57,"line":821},51,[55,823,453],{"class":65},[55,825,827],{"class":57,"line":826},52,[55,828,236],{"emptyLinePlaceholder":235},[55,830,832,834,836,839],{"class":57,"line":831},53,[55,833,561],{"class":65},[55,835,658],{"class":443},[55,837,838],{"class":139}," EndHeader",[55,840,718],{"class":65},[55,842,844,846,848,850,852,854,856,859,861],{"class":57,"line":843},54,[55,845,808],{"class":65},[55,847,692],{"class":586},[55,849,590],{"class":61},[55,851,689],{"class":65},[55,853,692],{"class":586},[55,855,773],{"class":61},[55,857,858],{"class":65}," headerBlock.",[55,860,727],{"class":586},[55,862,229],{"class":65},[55,864,866],{"class":57,"line":865},55,[55,867,453],{"class":65},[55,869,871],{"class":57,"line":870},56,[55,872,236],{"emptyLinePlaceholder":235},[55,874,876,878,880,883],{"class":57,"line":875},57,[55,877,561],{"class":65},[55,879,658],{"class":443},[55,881,882],{"class":139}," EndBlock",[55,884,718],{"class":65},[55,886,888,891,893,895,897,899,901,904,906],{"class":57,"line":887},58,[55,889,890],{"class":65},"        currentBlock.",[55,892,692],{"class":586},[55,894,590],{"class":61},[55,896,689],{"class":65},[55,898,692],{"class":586},[55,900,773],{"class":61},[55,902,903],{"class":65}," currentBlock.",[55,905,727],{"class":586},[55,907,229],{"class":65},[55,909,911,914,917],{"class":57,"line":910},59,[55,912,913],{"class":65},"        blocks.",[55,915,916],{"class":139},"Add",[55,918,919],{"class":65},"(currentBlock);\n",[55,921,923],{"class":57,"line":922},60,[55,924,453],{"class":65},[55,926,928],{"class":57,"line":927},61,[55,929,236],{"emptyLinePlaceholder":235},[55,931,933,935,937,940,942,944],{"class":57,"line":932},62,[55,934,561],{"class":65},[55,936,658],{"class":443},[55,938,939],{"class":139}," Process",[55,941,143],{"class":65},[55,943,570],{"class":443},[55,945,946],{"class":65}," split) {\n",[55,948,950,953,955,957,960,963,965,968,970],{"class":57,"line":949},63,[55,951,952],{"class":65},"        String header ",[55,954,76],{"class":61},[55,956,689],{"class":65},[55,958,959],{"class":139},"ToString",[55,961,962],{"class":65},"(headerBlock.",[55,964,727],{"class":586},[55,966,967],{"class":65},", headerBlock.",[55,969,692],{"class":586},[55,971,972],{"class":65},");\n",[55,974,976,979,981,983,985,988,990,993,995],{"class":57,"line":975},64,[55,977,978],{"class":65},"        String footer ",[55,980,76],{"class":61},[55,982,689],{"class":65},[55,984,959],{"class":139},[55,986,987],{"class":65},"(footerBlock.",[55,989,727],{"class":586},[55,991,992],{"class":65},", footerBlock.",[55,994,692],{"class":586},[55,996,972],{"class":65},[55,998,1000,1002,1005],{"class":57,"line":999},65,[55,1001,913],{"class":65},[55,1003,1004],{"class":139},"Reverse",[55,1006,512],{"class":65},[55,1008,1010,1013,1016,1019],{"class":57,"line":1009},66,[55,1011,1012],{"class":139},"        foreach",[55,1014,1015],{"class":65},"(Block block ",[55,1017,1018],{"class":61},"in",[55,1020,1021],{"class":65}," blocks) {\n",[55,1023,1025,1028,1030,1033,1036,1039,1042],{"class":57,"line":1024},67,[55,1026,1027],{"class":65},"            String fileName ",[55,1029,76],{"class":61},[55,1031,1032],{"class":65}," Path.",[55,1034,1035],{"class":139},"Combine",[55,1037,1038],{"class":65},"(OutputPath, block.",[55,1040,1041],{"class":586},"Name",[55,1043,972],{"class":65},[55,1045,1047,1050],{"class":57,"line":1046},68,[55,1048,1049],{"class":139},"            if",[55,1051,1052],{"class":65}," (split) {\n",[55,1054,1056,1059,1061,1064,1067,1069,1071,1074,1076,1079,1081,1084,1086],{"class":57,"line":1055},69,[55,1057,1058],{"class":65},"                String content ",[55,1060,76],{"class":61},[55,1062,1063],{"class":65}," header ",[55,1065,1066],{"class":61},"+",[55,1068,689],{"class":65},[55,1070,959],{"class":139},[55,1072,1073],{"class":65},"(block.",[55,1075,727],{"class":586},[55,1077,1078],{"class":65},", block.",[55,1080,692],{"class":586},[55,1082,1083],{"class":65},") ",[55,1085,1066],{"class":61},[55,1087,1088],{"class":65}," footer;\n",[55,1090,1092,1095,1098],{"class":57,"line":1091},70,[55,1093,1094],{"class":65},"                strategy.",[55,1096,1097],{"class":139},"CreateFile",[55,1099,1100],{"class":65},"(fileName, content);\n",[55,1102,1104,1107,1110,1112,1114,1116,1118],{"class":57,"line":1103},71,[55,1105,1106],{"class":65},"                template.",[55,1108,1109],{"class":139},"Remove",[55,1111,1073],{"class":65},[55,1113,727],{"class":586},[55,1115,1078],{"class":65},[55,1117,692],{"class":586},[55,1119,972],{"class":65},[55,1121,1123],{"class":57,"line":1122},72,[55,1124,1125],{"class":65},"            } else {\n",[55,1127,1129,1131,1134],{"class":57,"line":1128},73,[55,1130,1094],{"class":65},[55,1132,1133],{"class":139},"DeleteFile",[55,1135,1136],{"class":65},"(fileName);\n",[55,1138,1140],{"class":57,"line":1139},74,[55,1141,1142],{"class":65},"            }\n",[55,1144,1146],{"class":57,"line":1145},75,[55,1147,1148],{"class":65},"        }\n",[55,1150,1152],{"class":57,"line":1151},76,[55,1153,453],{"class":65},[55,1155,1157],{"class":57,"line":1156},77,[55,1158,1159],{"class":65},"}\n",[55,1161,1163],{"class":57,"line":1162},78,[55,1164,236],{"emptyLinePlaceholder":235},[55,1166,1168],{"class":57,"line":1167},79,[55,1169,1170],{"class":65},"class ManagementStrategy\n",[55,1172,1174],{"class":57,"line":1173},80,[55,1175,422],{"class":65},[55,1177,1179,1182,1184],{"class":57,"line":1178},81,[55,1180,1181],{"class":65},"    internal static ManagementStrategy ",[55,1183,637],{"class":139},[55,1185,1186],{"class":65},"(ITextTemplatingEngineHost host) {\n",[55,1188,1190,1193,1196,1199,1202,1204,1207,1209,1212,1215,1218,1220,1223],{"class":57,"line":1189},82,[55,1191,1192],{"class":139},"        return",[55,1194,1195],{"class":65}," (host ",[55,1197,1198],{"class":164},"is",[55,1200,1201],{"class":69}," IServiceProvider",[55,1203,1083],{"class":65},[55,1205,1206],{"class":61},"?",[55,1208,480],{"class":164},[55,1210,1211],{"class":69}," VSManagementStrategy",[55,1213,1214],{"class":65},"(host) ",[55,1216,1217],{"class":61},":",[55,1219,480],{"class":164},[55,1221,1222],{"class":69}," ManagementStrategy",[55,1224,640],{"class":65},[55,1226,1228],{"class":57,"line":1227},83,[55,1229,453],{"class":65},[55,1231,1233],{"class":57,"line":1232},84,[55,1234,236],{"emptyLinePlaceholder":235},[55,1236,1238,1241,1244],{"class":57,"line":1237},85,[55,1239,1240],{"class":65},"    internal ",[55,1242,1243],{"class":139},"ManagementStrategy",[55,1245,1246],{"class":65},"(ITextTemplatingEngineHost host) { }\n",[55,1248,1250],{"class":57,"line":1249},86,[55,1251,236],{"emptyLinePlaceholder":235},[55,1253,1255,1258,1260,1263],{"class":57,"line":1254},87,[55,1256,1257],{"class":65},"    internal virtual ",[55,1259,658],{"class":443},[55,1261,1262],{"class":139}," CreateFile",[55,1264,1265],{"class":65},"(String fileName, String content) {\n",[55,1267,1269,1272,1275],{"class":57,"line":1268},88,[55,1270,1271],{"class":65},"        File.",[55,1273,1274],{"class":139},"WriteAllText",[55,1276,1100],{"class":65},[55,1278,1280],{"class":57,"line":1279},89,[55,1281,453],{"class":65},[55,1283,1285],{"class":57,"line":1284},90,[55,1286,236],{"emptyLinePlaceholder":235},[55,1288,1290,1292,1294,1297],{"class":57,"line":1289},91,[55,1291,1257],{"class":65},[55,1293,658],{"class":443},[55,1295,1296],{"class":139}," DeleteFile",[55,1298,1299],{"class":65},"(String fileName) {\n",[55,1301,1303,1306,1309,1312],{"class":57,"line":1302},92,[55,1304,1305],{"class":139},"        if",[55,1307,1308],{"class":65}," (File.",[55,1310,1311],{"class":139},"Exists",[55,1313,1314],{"class":65},"(fileName))\n",[55,1316,1318,1321,1324],{"class":57,"line":1317},93,[55,1319,1320],{"class":65},"            File.",[55,1322,1323],{"class":139},"Delete",[55,1325,1136],{"class":65},[55,1327,1329],{"class":57,"line":1328},94,[55,1330,453],{"class":65},[55,1332,1334],{"class":57,"line":1333},95,[55,1335,1159],{"class":65},[55,1337,1339],{"class":57,"line":1338},96,[55,1340,236],{"emptyLinePlaceholder":235},[55,1342,1344,1347,1349],{"class":57,"line":1343},97,[55,1345,1346],{"class":65},"class VSManagementStrategy ",[55,1348,1217],{"class":61},[55,1350,1351],{"class":65}," ManagementStrategy\n",[55,1353,1355],{"class":57,"line":1354},98,[55,1356,422],{"class":65},[55,1358,1360,1363,1366],{"class":57,"line":1359},99,[55,1361,1362],{"class":65},"    private EnvDTE.",[55,1364,1365],{"class":586},"ProjectItem",[55,1367,1368],{"class":65}," templateProjectItem;\n",[55,1370,1372],{"class":57,"line":1371},100,[55,1373,236],{"emptyLinePlaceholder":235},[55,1375,1377,1379,1382,1385,1387,1391],{"class":57,"line":1376},101,[55,1378,1240],{"class":65},[55,1380,1381],{"class":139},"VSManagementStrategy",[55,1383,1384],{"class":65},"(ITextTemplatingEngineHost host) ",[55,1386,1217],{"class":61},[55,1388,1390],{"class":1389},"stJs5"," base",[55,1392,1393],{"class":65},"(host) {\n",[55,1395,1397,1400,1402,1405,1408],{"class":57,"line":1396},102,[55,1398,1399],{"class":65},"        IServiceProvider hostServiceProvider ",[55,1401,76],{"class":61},[55,1403,1404],{"class":65}," (",[55,1406,1407],{"class":69},"IServiceProvider",[55,1409,1410],{"class":65},")host;\n",[55,1412,1414,1416,1419,1422,1425],{"class":57,"line":1413},103,[55,1415,1305],{"class":139},[55,1417,1418],{"class":65}," (hostServiceProvider ",[55,1420,1421],{"class":61},"==",[55,1423,1424],{"class":275}," null",[55,1426,1427],{"class":65},")\n",[55,1429,1431,1434,1436,1439,1441,1443,1446,1448],{"class":57,"line":1430},104,[55,1432,1433],{"class":164},"            throw",[55,1435,480],{"class":164},[55,1437,1438],{"class":69}," ArgumentNullException",[55,1440,143],{"class":65},[55,1442,80],{"class":79},[55,1444,1445],{"class":83},"Could not obtain hostServiceProvider",[55,1447,80],{"class":79},[55,1449,972],{"class":65},[55,1451,1453],{"class":57,"line":1452},105,[55,1454,236],{"emptyLinePlaceholder":235},[55,1456,1458,1461,1464,1467,1469,1471,1474,1476,1478,1481,1484,1486,1489,1491,1493,1495,1497],{"class":57,"line":1457},106,[55,1459,1460],{"class":65},"        EnvDTE.",[55,1462,1463],{"class":586},"DTE",[55,1465,1466],{"class":65}," dte ",[55,1468,76],{"class":61},[55,1470,1404],{"class":65},[55,1472,1473],{"class":69},"EnvDTE",[55,1475,583],{"class":65},[55,1477,1463],{"class":69},[55,1479,1480],{"class":65},")hostServiceProvider.",[55,1482,1483],{"class":139},"GetService",[55,1485,143],{"class":65},[55,1487,1488],{"class":164},"typeof",[55,1490,143],{"class":65},[55,1492,1473],{"class":69},[55,1494,583],{"class":65},[55,1496,1463],{"class":69},[55,1498,1499],{"class":65},"));\n",[55,1501,1503,1505,1508,1510,1512],{"class":57,"line":1502},107,[55,1504,1305],{"class":139},[55,1506,1507],{"class":65}," (dte ",[55,1509,1421],{"class":61},[55,1511,1424],{"class":275},[55,1513,1427],{"class":65},[55,1515,1517,1519,1521,1523,1525,1527,1530,1532],{"class":57,"line":1516},108,[55,1518,1433],{"class":164},[55,1520,480],{"class":164},[55,1522,1438],{"class":69},[55,1524,143],{"class":65},[55,1526,80],{"class":79},[55,1528,1529],{"class":83},"Could not obtain DTE from host",[55,1531,80],{"class":79},[55,1533,972],{"class":65},[55,1535,1537],{"class":57,"line":1536},109,[55,1538,236],{"emptyLinePlaceholder":235},[55,1540,1542,1545,1547,1550,1553,1555,1558,1561,1564],{"class":57,"line":1541},110,[55,1543,1544],{"class":65},"        templateProjectItem ",[55,1546,76],{"class":61},[55,1548,1549],{"class":65}," dte.",[55,1551,1552],{"class":586},"Solution",[55,1554,583],{"class":65},[55,1556,1557],{"class":139},"FindProjectItem",[55,1559,1560],{"class":65},"(host.",[55,1562,1563],{"class":586},"TemplateFile",[55,1565,972],{"class":65},[55,1567,1569],{"class":57,"line":1568},111,[55,1570,453],{"class":65},[55,1572,1574],{"class":57,"line":1573},112,[55,1575,236],{"emptyLinePlaceholder":235},[55,1577,1579,1582,1584,1586],{"class":57,"line":1578},113,[55,1580,1581],{"class":65},"    internal override ",[55,1583,658],{"class":443},[55,1585,1262],{"class":139},[55,1587,1265],{"class":65},[55,1589,1591,1594,1596,1598],{"class":57,"line":1590},114,[55,1592,1593],{"class":1389},"        base",[55,1595,583],{"class":65},[55,1597,1097],{"class":139},[55,1599,1100],{"class":65},[55,1601,1603,1606,1609,1612,1615,1618,1621,1623,1626,1629,1632,1634,1637,1640,1642,1644,1646,1648,1650],{"class":57,"line":1602},115,[55,1604,1605],{"class":65},"        ((",[55,1607,1608],{"class":69},"EventHandler",[55,1610,1611],{"class":65},")",[55,1613,1614],{"class":443},"delegate",[55,1616,1617],{"class":65}," { templateProjectItem.",[55,1619,1620],{"class":586},"ProjectItems",[55,1622,583],{"class":65},[55,1624,1625],{"class":139},"AddFromFile",[55,1627,1628],{"class":65},"(fileName); }).",[55,1630,1631],{"class":139},"BeginInvoke",[55,1633,143],{"class":65},[55,1635,1636],{"class":275},"null",[55,1638,1639],{"class":65},", ",[55,1641,1636],{"class":275},[55,1643,1639],{"class":65},[55,1645,1636],{"class":275},[55,1647,1639],{"class":65},[55,1649,1636],{"class":275},[55,1651,972],{"class":65},[55,1653,1655],{"class":57,"line":1654},116,[55,1656,453],{"class":65},[55,1658,1660],{"class":57,"line":1659},117,[55,1661,236],{"emptyLinePlaceholder":235},[55,1663,1665,1667,1669,1671],{"class":57,"line":1664},118,[55,1666,1581],{"class":65},[55,1668,658],{"class":443},[55,1670,1296],{"class":139},[55,1672,1299],{"class":65},[55,1674,1676,1678,1680,1682,1684,1687,1690,1692,1694,1696,1698,1700,1702,1704,1706,1708,1710],{"class":57,"line":1675},119,[55,1677,1605],{"class":65},[55,1679,1608],{"class":69},[55,1681,1611],{"class":65},[55,1683,1614],{"class":443},[55,1685,1686],{"class":65}," { ",[55,1688,1689],{"class":139},"FindAndDeleteFile",[55,1691,1628],{"class":65},[55,1693,1631],{"class":139},[55,1695,143],{"class":65},[55,1697,1636],{"class":275},[55,1699,1639],{"class":65},[55,1701,1636],{"class":275},[55,1703,1639],{"class":65},[55,1705,1636],{"class":275},[55,1707,1639],{"class":65},[55,1709,1636],{"class":275},[55,1711,972],{"class":65},[55,1713,1715],{"class":57,"line":1714},120,[55,1716,453],{"class":65},[55,1718,1720],{"class":57,"line":1719},121,[55,1721,236],{"emptyLinePlaceholder":235},[55,1723,1725,1728,1730,1733],{"class":57,"line":1724},122,[55,1726,1727],{"class":65},"    private ",[55,1729,658],{"class":443},[55,1731,1732],{"class":139}," FindAndDeleteFile",[55,1734,1299],{"class":65},[55,1736,1738,1740,1743,1745,1748,1750,1753,1755],{"class":57,"line":1737},123,[55,1739,1012],{"class":139},[55,1741,1742],{"class":65},"(EnvDTE.",[55,1744,1365],{"class":586},[55,1746,1747],{"class":65}," projectItem ",[55,1749,1018],{"class":61},[55,1751,1752],{"class":65}," templateProjectItem.",[55,1754,1620],{"class":586},[55,1756,1757],{"class":65},") {\n",[55,1759,1761,1763,1766,1769,1771,1774,1776,1778],{"class":57,"line":1760},124,[55,1762,1049],{"class":139},[55,1764,1765],{"class":65}," (projectItem.",[55,1767,1768],{"class":139},"get_FileNames",[55,1770,143],{"class":65},[55,1772,1773],{"class":275},"0",[55,1775,1083],{"class":65},[55,1777,1421],{"class":61},[55,1779,1780],{"class":65}," fileName) {\n",[55,1782,1784,1787,1789],{"class":57,"line":1783},125,[55,1785,1786],{"class":65},"                projectItem.",[55,1788,1323],{"class":139},[55,1790,512],{"class":65},[55,1792,1794],{"class":57,"line":1793},126,[55,1795,1796],{"class":65},"                return;\n",[55,1798,1800],{"class":57,"line":1799},127,[55,1801,1142],{"class":65},[55,1803,1805],{"class":57,"line":1804},128,[55,1806,1148],{"class":65},[55,1808,1810],{"class":57,"line":1809},129,[55,1811,453],{"class":65},[55,1813,1815,1818],{"class":57,"line":1814},130,[55,1816,1817],{"class":65},"}#",[55,1819,156],{"class":61},[13,1821,1822],{},[1823,1824,1825],"em",{},"[)amien",[1827,1828,1829],"style",{},"html pre.shiki code .s9HRq, html code.shiki .s9HRq{--shiki-default:#F57D26;--shiki-dark:#FF79C6}html pre.shiki code .s6Vpi, html code.shiki .s6Vpi{--shiki-default:#5C6A72;--shiki-dark:#F8F8F2}html pre.shiki code .snuxY, html code.shiki .snuxY{--shiki-default:#3A94C5;--shiki-default-font-style:inherit;--shiki-dark:#8BE9FD;--shiki-dark-font-style:italic}html pre.shiki code .sciFF, html code.shiki .sciFF{--shiki-default:#8DA101;--shiki-dark:#E9F284}html pre.shiki code .sJQOs, html code.shiki .sJQOs{--shiki-default:#8DA101;--shiki-dark:#F1FA8C}html pre.shiki code .sZQI_, html code.shiki .sZQI_{--shiki-default:#5C6A72;--shiki-dark:#FF79C6}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sS4Kt, html code.shiki .sS4Kt{--shiki-default:#8DA101;--shiki-dark:#50FA7B}html pre.shiki code .smiwp, html code.shiki .smiwp{--shiki-default:#F85552;--shiki-dark:#FF79C6}html pre.shiki code .sPLAf, html code.shiki .sPLAf{--shiki-default:#3A94C5;--shiki-dark:#8BE9FD}html pre.shiki code .sSX4p, html code.shiki .sSX4p{--shiki-default:#939F91;--shiki-default-font-style:italic;--shiki-dark:#6272A4;--shiki-dark-font-style:inherit}html pre.shiki code .sjYfO, html code.shiki .sjYfO{--shiki-default:#DF69BA;--shiki-default-font-style:inherit;--shiki-dark:#8BE9FD;--shiki-dark-font-style:italic}html pre.shiki code .s3Ipq, html code.shiki .s3Ipq{--shiki-default:#DF69BA;--shiki-dark:#BD93F9}html pre.shiki code .sXAHl, html code.shiki .sXAHl{--shiki-default:#3A94C5;--shiki-dark:#FF79C6}html pre.shiki code .sKO3f, html code.shiki .sKO3f{--shiki-default:#DF69BA;--shiki-default-font-style:inherit;--shiki-dark:#BD93F9;--shiki-dark-font-style:italic}html pre.shiki code .sSKRk, html code.shiki .sSKRk{--shiki-default:#35A77C;--shiki-dark:#F8F8F2}html pre.shiki code .stJs5, html code.shiki .stJs5{--shiki-default:#5C6A72;--shiki-default-font-style:inherit;--shiki-dark:#BD93F9;--shiki-dark-font-style:italic}",{"title":50,"searchDepth":102,"depth":102,"links":1831},[1832,1838],{"id":34,"depth":102,"text":35,"children":1833},[1834,1835,1836,1837],{"id":39,"depth":112,"text":40},{"id":120,"depth":112,"text":121},{"id":189,"depth":112,"text":190},{"id":253,"depth":112,"text":254},{"id":288,"depth":102,"text":289},"Development","2009-01-22T11:53:13+00:00","A reusable Manager helper class for T4 templates that lets you split generated output into a file per block, for example one file per entity, with shared header and footer support.","[object Object]","md",null,false,{},"\u002Fblog\u002F2009\u002Fmultiple-outputs-from-t4-made-easy",{"title":5,"description":1841},"blog\u002F2009\u002Fmultiple-outputs-from-t4-made-easy",[1851,1852,1853],".NET","T4","C#","\u002Fblog\u002F2009\u002Fmultiple-outputs-from-t4-made-easy\u002F",1117,"dHGQyRKhBHyBk_95XasUjndSDMKtGZ7ufws5fqiPQuc",[1858,1862,1866],{"title":1859,"date":1860,"url":1861},"Transactions in the MongoDB EF Core Provider","2025-10-25","\u002Fblog\u002F2025\u002Fmongodb-explicit-transactions\u002F",{"title":1863,"date":1864,"url":1865},"Queryable Encryption with the MongoDB EF Core Provider","2025-09-22","\u002Fblog\u002F2025\u002Fmongodb-queryable-encryption\u002F",{"title":1867,"date":1868,"url":1869},"Lazy Loading with EF Core Proxies","2025-04-02","\u002Fblog\u002F2025\u002Fef-proxies\u002F",[],1780900527756]