fork download
  1. <#
  2. /*
  3. http://i...content-available-to-author-only...t.com
  4. use envDte to retrieve interface info, create an class for that interface
  5.  
  6. */
  7. #>
  8. <#@ template language="C#" debug="true" hostspecific="true" #>
  9. <#@ assembly name="System.Core" #>
  10. <#@ assembly name="System.Xml" #>
  11. <#@ assembly name="Microsoft.CSharp" #>
  12. <#@ assembly name="Microsoft.VisualStudio.Shell.Interop.8.0" #>
  13. <#@ assembly name="EnvDTE" #>
  14. <#@ assembly name="EnvDTE80" #>
  15. <#@ assembly name="VSLangProj" #>
  16. <#@ import namespace="System.Collections.Generic" #>
  17. <#@ import namespace="System.IO" #>
  18. <#@ import namespace="System.Linq" #>
  19. <#@ import namespace="System.Text" #>
  20. <#@ import namespace="System.Text.RegularExpressions" #>
  21. <#@ import namespace="Microsoft.VisualStudio.Shell.Interop" #>
  22. <#@ import namespace="EnvDTE" #>
  23. <#@ import namespace="EnvDTE80" #>
  24. <#@ import namespace="Microsoft.VisualStudio.TextTemplating"#>
  25. <# // To debug, uncomment the next two lines !!
  26. //System.Diagnostics.Debugger.Launch();
  27. //System.Diagnostics.Debugger.Break();
  28. #>
  29. <#PrepareDataToRender(this); #>
  30. <#var manager = Manager.Create(Host, GenerationEnvironment); #>
  31. <#manager.StartHeader(); #>// <auto-generated />
  32. // This file was generated by a T4 template.
  33. // Don't change it directly as your change would get overwritten. Instead, make changes
  34. // to the .tt file (i.e. the T4 template) and save it to regenerate this file.
  35.  
  36. // Make sure the compiler doesn't complain about missing Xml comments
  37. #pragma warning disable 1591
  38. using System;
  39.  
  40. <# if(GenerateMapper) { #>
  41. using System.Collections.Generic;
  42. <# } #>
  43. <# manager.EndBlock();#>
  44. <#
  45.  
  46.  
  47. var rootNamespace = Project.Properties.Item("RootNamespace").Value.ToString();
  48. #>
  49. //Project:<#=Project.Name#>
  50. //rootNamespace=<#= rootNamespace #>
  51. <# RecurseProjectItems(manager,Project.ProjectItems);
  52.  
  53. if(string.IsNullOrEmpty(CurrentNamespaceGenerating)==false)
  54. WriteLine("} //end namespace2");
  55.  
  56.  
  57. #>
  58.  
  59. <#manager.Process(SplitIntoMultipleFiles);#>
  60. <#@ Include File="DTOGenerator.tt.settings.t4" #>
  61. <#@ Include File="GenerateDictionaryMapper.tt" #>
  62. <#+
  63. string CurrentNamespaceGenerating=null;
  64. void RecurseProjectItems(Manager manager,ProjectItems container)
  65. {
  66. foreach(var item in container.Cast<ProjectItem>())
  67. {
  68. if(item.FileCodeModel==null)
  69. {
  70. if(IncludeDiagnostics)WriteLine("//opening container:"+item.Name);
  71. RecurseProjectItems(manager,item.ProjectItems);
  72. continue;
  73. }
  74. DateTime lastWriteTime=File.GetLastWriteTime(item.get_FileNames(0));
  75.  
  76. if(IncludeDiagnostics)WriteLine("//Found CodeModel:"+item.FileCodeModel.GetType().FullName);
  77. var interfaces=RecurseForInterfaces(manager,item.FileCodeModel.CodeElements,string.Empty)
  78. .OrderBy(ri=>ri.Item2)
  79. .ThenByDescending(ri=>ri.Item1.Name).ToArray();
  80. if(interfaces.Length>1 && interfaces[0].Item1.Name==interfaces[1].Item1.Name+"DTO")
  81. interfaces=interfaces.Except(new[]{interfaces[1]}).ToArray();
  82. foreach(var i in interfaces)
  83. {
  84. if(IncludeDiagnostics)
  85. WriteLine("//Found Interface:"+i.Item1.Name);
  86. var properties=RecurseForProperties(i.Item1);
  87. if(properties.Count()>0)
  88. WriteInterface(manager,i.Item1,properties,i.Item2);
  89. }
  90.  
  91.  
  92. }
  93. }
  94.  
  95.  
  96. IEnumerable<Tuple<string,Action<bool>>> RecurseForProperties(CodeInterface2 codeInterface)
  97. {
  98. var names=new HashSet<string>();
  99. if(codeInterface.Bases !=null)
  100. foreach(var baseInterface in codeInterface.Bases.Cast<CodeElement>())
  101. {
  102. if(IncludeDiagnostics) WriteLine("//found base:"+baseInterface.Name);
  103. foreach(var item in RecurseForProperties(((CodeInterface2)baseInterface)))
  104. {
  105. if(names.Contains(item.Item1)==false)
  106. {
  107. names.Add(item.Item1);
  108. yield return item;
  109. }
  110. }
  111. }
  112. foreach( CodeProperty item in codeInterface.Members.OfType<CodeProperty>())
  113. {
  114. if(names.Contains(item.Name)==false)
  115. {
  116. names.Add(item.Name);
  117. yield return Tuple.Create<string,Action<bool>>(item.Name,asInterfaceSetter=> WriteMapping(item,asInterfaceSetter));
  118. }
  119. }
  120. }
  121.  
  122. IEnumerable<Tuple<CodeInterface2,string>> RecurseForInterfaces(Manager manager, CodeElements codeElements,string currentNamespace )
  123. {
  124.  
  125. var q=codeElements.Cast<CodeElement>( )
  126. //.Where(x =>x is CodeInterface||x is CodeClass || x is CodeNamespace) //&& ((CodeInterface)x).Attributes.Count>0)
  127. //.Where(x => x.Name.StartsWith("System")==false)
  128. //.Where(x => x.Name.StartsWith("Infragistics")==false)
  129. //.Where(x => x.Name.StartsWith("Microsoft")==false)
  130. //.Where(x => x.Name.StartsWith("ICSharpCode")==false)
  131. ;
  132. var interfaces=new List<string>();
  133.  
  134. foreach (CodeElement element in q)
  135. {
  136.  
  137. if (element is CodeInterface && interfaces.Contains(element.Name)==false)
  138. {
  139. var c = (CodeInterface2)element;
  140. //verify element is a project element not an external
  141. if (c.InfoLocation!=vsCMInfoLocation.vsCMInfoLocationProject)
  142. continue;
  143. yield return Tuple.Create<CodeInterface2,string>(c,currentNamespace);
  144.  
  145. }
  146.  
  147. if (element is CodeNamespace)
  148. {
  149. var ns=(CodeNamespace)element;
  150. if(SkippedNamespaces.Contains( ns.Name)==false)
  151. foreach(var find in RecurseForInterfaces(manager,ns.Members,ns.Name))
  152. yield return find;
  153. }
  154. }
  155.  
  156.  
  157. }
  158.  
  159. void WriteMapping(CodeProperty codeProperty,bool asInterfaceSetter)
  160. {
  161. WriteLine("");
  162. WriteLine("///<summary>");
  163. WriteLine("///"+codeProperty.FullName);
  164. WriteLine("///</summary>");
  165. if(codeProperty.Getter==null && codeProperty.Setter==null)
  166. return;
  167. if(codeProperty.Attributes!=null){
  168. foreach(CodeAttribute a in codeProperty.Attributes)
  169. {
  170. Write("["+a.FullName);
  171. if(a.Children!=null && a.Children.Count>0)
  172. {
  173. var start=a.Children.Cast<CodeElement>().First().GetStartPoint();
  174. var finish= a.GetEndPoint();
  175. string wholeAttributeLine=start.CreateEditPoint().GetText(finish);
  176.  
  177. Write("("+wholeAttributeLine);
  178. }
  179. WriteLine("]");
  180. }
  181. }
  182. if(asInterfaceSetter==false){
  183. Write("public ");
  184. } else {
  185. Write("new ");
  186. }
  187. Write(GetFullName(codeProperty.Type) +" "+codeProperty.Prototype);
  188.  
  189. Write(" {");
  190. if(asInterfaceSetter==false)
  191. Write("get;");
  192. Write("set;");
  193. WriteLine("}");
  194.  
  195. }
  196. string GetFullName(CodeTypeRef codeType)
  197. {
  198. string fullName;
  199.  
  200. if (codeType.TypeKind == vsCMTypeRef.vsCMTypeRefArray)
  201. {
  202. CodeTypeRef arrayType = codeType.ElementType;
  203. fullName = arrayType.AsFullName + "[]";
  204. }
  205. else
  206. {
  207. fullName = codeType.AsFullName;
  208. }
  209. return fullName;
  210. }
  211. void WriteInterface(Manager manager,CodeInterface2 codeInterface, IEnumerable<Tuple<string,Action<bool>>> writeProperties,string parentNamespace)
  212. {
  213.  
  214. if(IncludeDiagnostics)WriteLine("//CodeInterface parentNamespace:"+parentNamespace);
  215. var xmlBlock="\t//CodeInterface";
  216.  
  217. var start=codeInterface.GetStartPoint();
  218.  
  219. var finish=codeInterface.Children!=null && codeInterface.Children.Count>0? codeInterface.Children.Cast<CodeElement>().First().GetStartPoint() : codeInterface.GetEndPoint();//.GetEndPoint();
  220. string wholeInterfaceLine=start.CreateEditPoint().GetText(finish);
  221. var classLine=wholeInterfaceLine.ToString();
  222. var justProto=wholeInterfaceLine.Contains("{")?classLine.Substring(0,classLine.IndexOf("{")):classLine;
  223.  
  224. if(IncludeDiagnostics && justProto.Length<100 && justProto.Contains("*/")==false ){WriteLine("/* justProto: "+justProto); WriteLine(" */");}
  225.  
  226. manager.EndBlock();
  227.  
  228. var fullName=codeInterface.FullName;
  229. var name=fullName.Contains(".")?fullName.Substring(fullName.LastIndexOf('.')+1):fullName;
  230. if(name.StartsWith("I")) name=name.Substring(1);
  231. if(name.EndsWith("DTO")==false)
  232. name=name+"DTO";
  233. manager.StartNewFile(name+".generated.cs");
  234. if(IncludeDiagnostics) WriteLine("//fullName:"+fullName);
  235. if(IncludeDiagnostics)WriteLine("//name:"+name);
  236. var targetNamespace=GetTargetNamespace(codeInterface.Namespace.Name);
  237. if(codeInterface!=null && codeInterface.Namespace!=null && (targetNamespace != CurrentNamespaceGenerating|| SplitIntoMultipleFiles)){
  238.  
  239. if(string.IsNullOrEmpty(CurrentNamespaceGenerating)==false && SplitIntoMultipleFiles==false)
  240. WriteLine("} //namespace end1");
  241. CurrentNamespaceGenerating=GetTargetNamespace(codeInterface.Namespace.Name);
  242.  
  243. if(IncludeDiagnostics)WriteLine("//end namespace:"+CurrentNamespaceGenerating+":begin:"+codeInterface.Namespace.Name);
  244. #>
  245.  
  246. namespace <#=codeInterface.Namespace.Name#> {<#+ }
  247. if(GenerateWriteInterfaces && codeInterface.Name.EndsWith("DTO")==false){ #>
  248. public interface I<#=name#>:<#=codeInterface.Name#>{
  249. <#+ foreach(var item in writeProperties) {
  250. item.Item2(true); } #>
  251. }
  252. <#+ } #>
  253. <#+ if(codeInterface.FullName.EndsWith("DTO")){ return;}#>
  254. ///<seealso cref="<#=codeInterface.FullName#>"/>
  255. public partial class <#=name#>:<#=codeInterface.Name #><#=GenerateWriteInterfaces && codeInterface.Name.EndsWith("DTO")==false?"DTO":string.Empty#>{
  256. <#+
  257. PushIndent("\t");
  258. PushIndent("\t");
  259. foreach(var item in writeProperties)
  260. item.Item2(false);
  261. PopIndent();
  262. PopIndent();
  263. if(SplitIntoMultipleFiles)
  264. WriteLine("}");
  265.  
  266. if(GenerateMapper ){
  267. var dictionary=new Dictionary<string,bool>();
  268. writeProperties.ToList().ForEach(wp=>dictionary.Add(wp.Item1,false));
  269. //WriteLine("#pragma warning disable 0108");
  270. GenerateDictionaryMapper(codeInterface.Name,dictionary
  271. , CopyDictionaryNamespace,false);
  272. //WriteLine("#pragma warning restore 0108");
  273. }
  274. #>
  275. } //end class <#=name #>
  276.  
  277. <#+
  278.  
  279. }
  280. string ConvertFullName(CodeModel cm, string fullName)
  281. {
  282. // Convert a .NET type name into a C++ type name.
  283. if ((cm.Language == CodeModelLanguageConstants.vsCMLanguageVC) ||
  284. (cm.Language == CodeModelLanguageConstants.vsCMLanguageMC))
  285. return fullName.Replace(".", "::");
  286. else
  287. return fullName;
  288. }
  289. #>
  290. <#+
  291.  
  292. static DTE Dte;
  293. static Project Project;
  294.  
  295. static TextTransformation TT;
  296. static string T4FileName;
  297. static string T4Folder;
  298. static string AppRoot;
  299. static string GeneratedCode = @"GeneratedCode(""InterfaceT4"", ""2.0"")";
  300. static Microsoft.CSharp.CSharpCodeProvider codeProvider = new Microsoft.CSharp.CSharpCodeProvider();
  301.  
  302. void PrepareDataToRender(TextTransformation tt) {
  303. TT = tt;
  304. T4FileName = Path.GetFileName(Host.TemplateFile);
  305. T4Folder = Path.GetDirectoryName(Host.TemplateFile);
  306.  
  307. // Get the DTE service from the host
  308. var serviceProvider = Host as IServiceProvider;
  309. if (serviceProvider != null) {
  310. Dte = serviceProvider.GetService(typeof(SDTE)) as DTE;
  311. }
  312.  
  313. // Fail if we couldn't get the DTE. This can happen when trying to run in TextTransform.exe
  314. if (Dte == null) {
  315. throw new Exception("InterfaceT4 can only execute through the Visual Studio host");
  316. }
  317.  
  318. Project = GetProjectContainingT4File(Dte);
  319.  
  320. if (Project == null) {
  321. Error("Could not find the VS Project containing the T4 file.");
  322. return;
  323. }
  324.  
  325. // Get the path of the root folder of the app
  326. AppRoot = Path.GetDirectoryName(Project.FullName) + '\\';
  327.  
  328. }
  329.  
  330. Project GetProjectContainingT4File(DTE dte) {
  331.  
  332. // Find the .tt file's ProjectItem
  333. ProjectItem projectItem = dte.Solution.FindProjectItem(Host.TemplateFile);
  334.  
  335. // If the .tt file is not opened, open it
  336. if (projectItem.Document == null)
  337. projectItem.Open(Constants.vsViewKindCode);
  338.  
  339. if (AlwaysKeepTemplateDirty) {
  340. // Mark the .tt file as unsaved. This way it will be saved and update itself next time the
  341. // project is built. Basically, it keeps marking itself as unsaved to make the next build work.
  342. // Note: this is certainly hacky, but is the best I could come up with so far.
  343. projectItem.Document.Saved = false;
  344. }
  345.  
  346. return projectItem.ContainingProject;
  347. }
  348.  
  349.  
  350. #region Manager
  351. /*
  352.   Manager.tt from Damien Guard: http://d...content-available-to-author-only...g.com/blog/2009/11/06/multiple-outputs-from-t4-made-easy-revisited
  353. */
  354.  
  355.  
  356. // Manager class records the various blocks so it can split them up
  357. class Manager {
  358. private class Block {
  359. public String Name;
  360. public int Start, Length;
  361. }
  362.  
  363. private Block currentBlock;
  364. private List<Block> files = new List<Block>();
  365. private Block footer = new Block();
  366. private Block header = new Block();
  367. private ITextTemplatingEngineHost host;
  368. private StringBuilder template;
  369. protected List<String> generatedFileNames = new List<String>();
  370.  
  371. public static Manager Create(ITextTemplatingEngineHost host, StringBuilder template) {
  372. return (host is IServiceProvider) ? new VSManager(host, template) : new Manager(host, template);
  373. }
  374.  
  375. public void KeepGeneratedFile(String name) {
  376. name = Path.Combine(Path.GetDirectoryName(host.TemplateFile), name);
  377. generatedFileNames.Add(name);
  378. }
  379.  
  380. public void StartNewFile(String name) {
  381. if (name == null)
  382. throw new ArgumentNullException("name");
  383. CurrentBlock = new Block { Name = name };
  384. }
  385.  
  386. public void StartFooter() {
  387. CurrentBlock = footer;
  388. }
  389.  
  390. public void StartHeader() {
  391. CurrentBlock = header;
  392. }
  393.  
  394. public void EndBlock() {
  395. if (CurrentBlock == null)
  396. return;
  397. CurrentBlock.Length = template.Length - CurrentBlock.Start;
  398. if (CurrentBlock != header && CurrentBlock != footer)
  399. files.Add(CurrentBlock);
  400. currentBlock = null;
  401. }
  402.  
  403. public virtual void Process(bool split) {
  404. if (split) {
  405. EndBlock();
  406. String headerText = template.ToString(header.Start, header.Length);
  407. String footerText = template.ToString(footer.Start, footer.Length);
  408. String outputPath = Path.GetDirectoryName(host.TemplateFile);
  409. files.Reverse();
  410. foreach (Block block in files) {
  411. String fileName = Path.Combine(outputPath, block.Name);
  412. String content = headerText + template.ToString(block.Start, block.Length) + footerText;
  413. generatedFileNames.Add(fileName);
  414. CreateFile(fileName, content);
  415. template.Remove(block.Start, block.Length);
  416. }
  417. }
  418. }
  419.  
  420. protected virtual void CreateFile(String fileName, String content) {
  421. if (IsFileContentDifferent(fileName, content))
  422. File.WriteAllText(fileName, content);
  423. }
  424.  
  425. public virtual String GetCustomToolNamespace(String fileName) {
  426. return null;
  427. }
  428.  
  429. public virtual String DefaultProjectNamespace {
  430. get { return null; }
  431. }
  432.  
  433. protected bool IsFileContentDifferent(String fileName, String newContent) {
  434. return !(File.Exists(fileName) && File.ReadAllText(fileName) == newContent);
  435. }
  436.  
  437. private Manager(ITextTemplatingEngineHost host, StringBuilder template) {
  438. this.host = host;
  439. this.template = template;
  440. }
  441.  
  442. private Block CurrentBlock {
  443. get { return currentBlock; }
  444. set {
  445. if (CurrentBlock != null)
  446. EndBlock();
  447. if (value != null)
  448. value.Start = template.Length;
  449. currentBlock = value;
  450. }
  451. }
  452.  
  453. private class VSManager : Manager {
  454. private EnvDTE.ProjectItem templateProjectItem;
  455. private EnvDTE.DTE dte;
  456. private Action<String> checkOutAction;
  457. private Action<IEnumerable<String>> projectSyncAction;
  458.  
  459. public override String DefaultProjectNamespace {
  460. get {
  461. return templateProjectItem.ContainingProject.Properties.Item("DefaultNamespace").Value.ToString();
  462. }
  463. }
  464.  
  465. public override String GetCustomToolNamespace(string fileName) {
  466. return dte.Solution.FindProjectItem(fileName).Properties.Item("CustomToolNamespace").Value.ToString();
  467. }
  468.  
  469. public override void Process(bool split) {
  470. if (templateProjectItem.ProjectItems == null)
  471. return;
  472. base.Process(split);
  473. projectSyncAction.EndInvoke(projectSyncAction.BeginInvoke(generatedFileNames, null, null));
  474. }
  475.  
  476. protected override void CreateFile(String fileName, String content) {
  477. if (IsFileContentDifferent(fileName, content)) {
  478. CheckoutFileIfRequired(fileName);
  479. File.WriteAllText(fileName, content);
  480. }
  481. }
  482.  
  483. internal VSManager(ITextTemplatingEngineHost host, StringBuilder template)
  484. : base(host, template) {
  485. var hostServiceProvider = (IServiceProvider)host;
  486. if (hostServiceProvider == null)
  487. throw new ArgumentNullException("Could not obtain IServiceProvider");
  488. dte = (EnvDTE.DTE)hostServiceProvider.GetService(typeof(EnvDTE.DTE));
  489. if (dte == null)
  490. throw new ArgumentNullException("Could not obtain DTE from host");
  491. templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile);
  492. checkOutAction = (String fileName) => dte.SourceControl.CheckOutItem(fileName);
  493. projectSyncAction = (IEnumerable<String> keepFileNames) => ProjectSync(templateProjectItem, keepFileNames);
  494. }
  495.  
  496. private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, IEnumerable<String> keepFileNames) {
  497. var keepFileNameSet = new HashSet<String>(keepFileNames);
  498. var projectFiles = new Dictionary<String, EnvDTE.ProjectItem>();
  499. var originalFilePrefix = Path.GetFileNameWithoutExtension(templateProjectItem.get_FileNames(0)) + ".";
  500. foreach (EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems)
  501. projectFiles.Add(projectItem.get_FileNames(0), projectItem);
  502.  
  503. // Remove unused items from the project
  504. foreach (var pair in projectFiles)
  505. if (!keepFileNames.Contains(pair.Key) && !(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalFilePrefix))
  506. pair.Value.Delete();
  507.  
  508. // Add missing files to the project
  509. foreach (String fileName in keepFileNameSet)
  510. if (!projectFiles.ContainsKey(fileName))
  511. templateProjectItem.ProjectItems.AddFromFile(fileName);
  512. }
  513.  
  514. private void CheckoutFileIfRequired(String fileName) {
  515. var sc = dte.SourceControl;
  516. if (sc != null && sc.IsItemUnderSCC(fileName) && !sc.IsItemCheckedOut(fileName))
  517. checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null));
  518. }
  519. }
  520. }
  521.  
  522. /*
  523.   End of Manager.tt
  524. */
  525. #endregion
  526. #>
  527. <#+
  528. void GenerateDictionaryMapper(string businessName, IDictionary<string,bool> propertyWithCopyExclusions, string copyDictionaryNamespace,bool useStaticReflection)
  529. { #>
  530.  
  531. #region MappingMethods
  532. public static Dictionary<string,Action> GenerateActionDictionary<T>(T dest, <#=businessName #> source, bool includeIdentifier)
  533. where T: <#= businessName #>DTO
  534. {
  535. var result= new Dictionary<string,Action>()
  536. {
  537. <#+
  538. PushIndent("\t");
  539. PushIndent("\t");
  540. PushIndent("\t");
  541. PushIndent("\t");
  542. PushIndent("\t");
  543. PushIndent("\t");
  544. foreach(string item in propertyWithCopyExclusions.Keys)
  545. {
  546. if(propertyWithCopyExclusions[item]==false)
  547. {
  548. if(useStaticReflection){
  549. WriteLine("\t{source.ClassMemberName(x=>x."+item+"),");
  550. WriteLine("()=>dest."+item+"=source."+item+"},");
  551. } else{
  552. Write("\t{\""+item+"\",");
  553. WriteLine("()=>dest."+item+"=source."+item+"},");
  554. }
  555. }
  556. }
  557. PopIndent();
  558. PopIndent();
  559. PopIndent();
  560. PopIndent();
  561. PopIndent();
  562. PopIndent();
  563. #>
  564. };
  565. return result;}
  566.  
  567. public static T CopyData<T>(Func<T> creator, <#=businessName #> source, bool includeIdentifier,
  568. ICollection<string> excludeList) where T: <#=businessName#>DTO
  569. {
  570. return <#=copyDictionaryNamespace#>.CopyDictionary<T,<#= businessName #>>.CopyData(GenerateActionDictionary,creator,source,includeIdentifier, excludeList);
  571. }
  572.  
  573. #endregion MappingMethods
  574.  
  575. <#+
  576. } #>
  577. // CopyDictionary.cs
  578. using System;
  579. using System.Collections.Generic;
  580. using System.Linq;
  581. using System.Text;
  582. namespace Project.Shared.CrossCutting
  583. {
  584.  
  585. public interface IValidationDictionary
  586. {
  587. void AddError(string key, string errorMessage);
  588. bool IsValid { get; }
  589. }
  590. internal static class CopyDictionary<T, TU> where T : TU
  591. {
  592. public static T CopyData(Func<T, TU, bool, Dictionary<string, Action>> actionDictionaryFunc,
  593. Func<T> creator, TU source, bool includeIdentifier, ICollection<string> excludeList)
  594. {
  595. return CopyDataMaster(actionDictionaryFunc, creator, source, includeIdentifier, excludeList,
  596. kvp => kvp.Value());
  597. }
  598.  
  599. public static T CopyData(Func<T, TU, bool, Dictionary<string, Action>> actionDictionaryFunc,
  600. IValidationDictionary validation, Func<T> creator, TU source, bool includeIdentifier, ICollection<string> excludeList)
  601. {
  602. var result = CopyDataMaster(actionDictionaryFunc, creator, source, includeIdentifier, excludeList,
  603. kvp =>
  604. {
  605. try
  606. {
  607. kvp.Value();
  608. }
  609. catch (Exception exception)
  610. {
  611.  
  612. validation.AddError(kvp.Key, exception.Message);
  613.  
  614. }
  615. });
  616. if (validation.IsValid == false)
  617. throw new ArgumentException("Validation contains errors");
  618. return result;
  619. }
  620.  
  621. private static T CopyDataMaster(Func<T, TU, bool, Dictionary<string, Action>> actionDictionaryFunc,
  622. Func<T> creator, TU source, bool includeIdentifier, ICollection<string> excludeList,
  623. Action<KeyValuePair<string, Action>> action)
  624. {
  625. var result = creator();
  626. foreach (var kvp in actionDictionaryFunc(result, source, includeIdentifier))
  627. {
  628. if (excludeList == null || excludeList.Contains(kvp.Key) == false)
  629. action(kvp);
  630. }
  631. return result;
  632. }
  633. }
  634. }
  635.  
Not running #stdin #stdout 0s 0KB
stdin
<#+
/*

This file contains settings used by DTOGenerator.tt The main goal is to avoid the need for users
to fork the 'official' template in order to achieve what they want.

*/

IEnumerable<string> SkippedNamespaces=new[]{"Project.Shared.Behaviors","Project.Shared.CrossCutting","Project2.Shared.Behaviors"};

/// <remarks>Must be static so that GetTargetNamespace can reference it</remarks>
static bool IncludeDiagnostics=false;

Func<string,string> GetTargetNamespace=sourceNamespace=> {
	if(string.IsNullOrEmpty(sourceNamespace))
	{
		if(IncludeDiagnostics)
			System.Diagnostics.Debug.WriteLine("No Sourcenamespace found");
		return sourceNamespace;
	}
	if(sourceNamespace.Contains(".")==false){
		if(IncludeDiagnostics)
			System.Diagnostics.Debug.WriteLine("Sourcenamespace found");
		return sourceNamespace+".DTO";}
	return sourceNamespace.Substring(0,sourceNamespace.LastIndexOf('.'))+"DTO";
};//null;//"Project.Shared.DTO";
bool SplitIntoMultipleFiles = false;
bool AlwaysKeepTemplateDirty = false;
bool GenerateMapper=true;
bool GenerateWriteInterfaces=true;
string CopyDictionaryNamespace="Project.Shared.CrossCutting";
void RenderAdditionalCode() {
}
#>
stdout
Standard output is empty