PageRenderTime 52ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/Code/Source/Teaching.Core/Cli/CliSampleApplication.cs

https://bitbucket.org/BernhardGlueck/teaching
C# | 147 lines | 117 code | 27 blank | 3 comment | 9 complexity | 1181c3befa5ad89c37d3711c85aa3f9d MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel.Composition;
  4. using System.ComponentModel.Composition.Hosting;
  5. using System.ComponentModel.Composition.Primitives;
  6. using System.Diagnostics;
  7. using System.Diagnostics.Contracts;
  8. using System.Globalization;
  9. using System.IO;
  10. using System.Linq;
  11. using System.Reflection;
  12. using Teaching.Core.Profiling;
  13. namespace Teaching.Core.Cli
  14. {
  15. public sealed class CliSampleApplication
  16. {
  17. private readonly IEnumerable<Assembly> assemblies;
  18. private readonly TextWriter output;
  19. [ImportMany]
  20. private IEnumerable<Lazy<ICliSample, ICliSampleMetadata>> Samples { get; set; }
  21. public int Run(IEnumerable<string> arguments)
  22. {
  23. Contract.Requires<ArgumentNullException>( arguments != null,"arguments");
  24. var cliParser = new CliParser(arguments);
  25. output.WriteLine("Scanning the following assemblies for samples");
  26. foreach( var assembly in assemblies)
  27. {
  28. output.WriteLine(assembly);
  29. }
  30. var catalog = new AggregateCatalog(assemblies.Select(a => new AssemblyCatalog(a)));
  31. using( var container = new CompositionContainer(catalog) )
  32. {
  33. var batch = new CompositionBatch();
  34. batch.AddExportedValue(container);
  35. batch.AddExportedValue(catalog);
  36. batch.AddExportedValue(output);
  37. batch.AddExportedValue<ICliParser>(cliParser);
  38. container.Compose(batch);
  39. // This is not supported now, so we have to resort to an internal import
  40. //var samples = container.GetExportedValues<Lazy<ICliSample, ICliSampleMetadata>>().ToList();
  41. container.SatisfyImportsOnce(this);
  42. var sampleToRun = FindSample(cliParser.GetArgument("sample",string.Empty));
  43. var result = -1;
  44. if (sampleToRun == null)
  45. {
  46. output.WriteLine("No sample selected to execute on the command line");
  47. output.WriteLine();
  48. OutputLegend(Samples);
  49. output.WriteLine();
  50. output.WriteLine("Select sample to run interactivly by name or index: ");
  51. sampleToRun = FindSample(Console.ReadLine());
  52. output.WriteLine();
  53. }
  54. if ( sampleToRun != null )
  55. {
  56. result = ExecuteSample(sampleToRun);
  57. }
  58. if ( Debugger.IsAttached )
  59. {
  60. Console.ReadKey();
  61. }
  62. return result;
  63. }
  64. }
  65. private int ExecuteSample(Lazy<ICliSample,ICliSampleMetadata> sample)
  66. {
  67. output.WriteLine("Executing sample {0}",sample.Metadata.Name);
  68. // Force evaluation to finish initialization:
  69. var sampleInstance = sample.Value;
  70. using (new ProfiledSection(output, "Sample {1} executed in {0}", sample.Metadata.Name))
  71. {
  72. if (!Debugger.IsAttached)
  73. {
  74. try
  75. {
  76. sampleInstance.Execute();
  77. }
  78. catch (Exception ex)
  79. {
  80. output.WriteLine("An exception occured in sample {0}", sample.Metadata.Name);
  81. output.WriteLine(ex);
  82. return -1;
  83. }
  84. }
  85. else
  86. {
  87. sampleInstance.Execute();
  88. }
  89. }
  90. return 0;
  91. }
  92. private void OutputLegend(IEnumerable<Lazy<ICliSample,ICliSampleMetadata>> samples )
  93. {
  94. foreach( var sampleGroup in samples.GroupBy(s => s.Metadata.Index))
  95. {
  96. if ( sampleGroup.Count() > 1)
  97. {
  98. output.WriteLine("Sample {0} is duplicated",sampleGroup.Key);
  99. }
  100. }
  101. output.WriteLine("Available samples: ({0}) in total",samples.Count());
  102. output.WriteLine("");
  103. foreach( var sample in samples.OrderBy(s => s.Metadata.Index) )
  104. {
  105. output.WriteLine("{0}. {1} - {2}",sample.Metadata.Index,sample.Metadata.Name,sample.Metadata.Description);
  106. }
  107. }
  108. private Lazy<ICliSample,ICliSampleMetadata> FindSample(string selection)
  109. {
  110. return Samples.FirstOrDefault(s => s.Metadata.Index.ToString(CultureInfo.InvariantCulture) == selection) ??
  111. Samples.FirstOrDefault(
  112. s => s.Metadata.Name.Equals(selection, StringComparison.OrdinalIgnoreCase));
  113. }
  114. public CliSampleApplication(IEnumerable<Assembly> assemblies = null,TextWriter output = null)
  115. {
  116. this.assemblies = assemblies ?? new[] {Assembly.GetEntryAssembly()};
  117. this.output = output ?? Console.Out;
  118. }
  119. }
  120. }