public void GetTemplateFile() { using (var layout = new TestDirectoryLayout()) { layout.WritePluginFile("PluginA", "templates/__test_1.html", "test 1 in plugin a"); layout.WritePluginFile("PluginB", "templates/__test_1.html", "test 1 in plugin b"); var fileStorage = Application.Ioc.Resolve <IFileStorage>(); var fileEntry = fileStorage.GetTemplateFile("__test_1.html"); Assert.IsTrue(fileEntry.Exists); Assert.IsTrue(!string.IsNullOrEmpty(fileEntry.Filename)); Assert.IsTrue(!string.IsNullOrEmpty(fileEntry.UniqueIdentifier)); if (PlatformUtils.RunningOnWindows()) { // on unix there no file creation time Assert.IsTrue(fileEntry.CreationTimeUtc != DateTime.MinValue); } Assert.IsTrue(fileEntry.LastAccessTimeUtc != DateTime.MinValue); Assert.IsTrue(fileEntry.LastWriteTimeUtc != DateTime.MinValue); Assert.Equals(fileEntry.ReadAllText(), "test 1 in plugin b"); Assert.IsTrue(fileEntry.ReadAllBytes() .SequenceEqual(Encoding.UTF8.GetBytes("test 1 in plugin b"))); Assert.Throws <NotSupportedException>(() => fileEntry.WriteAllText("test readonly")); fileEntry = fileStorage.GetTemplateFile("__test_2.html"); Assert.IsTrue(!fileEntry.Exists); } }
/// <summary> /// Compile source files to assembly<br/> /// 编译源代码到程序集<br/> /// </summary> public void Compile(IList <string> sourceFiles, string assemblyName, string assemblyPath, CompilationOptions options) { // Use default options if `options` is null options = options ?? new CompilationOptions(); // Parse source files into syntax trees // Also define NETCORE for .Net Core var parseOptions = CSharpParseOptions.Default; #if NETCORE parseOptions = parseOptions.WithPreprocessorSymbols("NETCORE"); #endif var syntaxTrees = sourceFiles .Select(path => CSharpSyntaxTree.ParseText( File.ReadAllText(path), parseOptions, path, Encoding.UTF8)) .ToList(); // Find all using directive and load the namespace as assembly // It's for resolve assembly dependencies of plugin LoadAssembliesFromUsings(syntaxTrees); // Add loaded assemblies to compile references var assemblyLoader = Application.Ioc.Resolve <IAssemblyLoader>(); var references = assemblyLoader.GetLoadedAssemblies() .Select(assembly => assembly.Location) .Select(path => MetadataReference.CreateFromFile(path)) .ToList(); // Set roslyn compilation options // Generate pdb file only supported on windows, // because Microsoft.DiaSymReader.Native only have windows runtimes if (!PlatformUtils.RunningOnWindows()) { options.GeneratePdbFile = false; } var optimizationLevel = (options.Release ? OptimizationLevel.Release : OptimizationLevel.Debug); var pdbPath = ((!options.GeneratePdbFile) ? null : Path.Combine( Path.GetDirectoryName(assemblyPath), Path.GetFileNameWithoutExtension(assemblyPath) + ".pdb")); // Create compilation options and set IgnoreCorLibraryDuplicatedTypes flag // To avoid error like The type 'Path' exists in both // 'System.Runtime.Extensions, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' // and // 'System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' var compilationOptions = new CSharpCompilationOptions( OutputKind.DynamicallyLinkedLibrary, optimizationLevel: optimizationLevel); var withTopLevelBinderFlagsMethod = compilationOptions.GetType() .FastGetMethod("WithTopLevelBinderFlags", BindingFlags.Instance | BindingFlags.NonPublic); var binderFlagsType = withTopLevelBinderFlagsMethod.GetParameters()[0].ParameterType; compilationOptions = (CSharpCompilationOptions)withTopLevelBinderFlagsMethod.FastInvoke( compilationOptions, binderFlagsType.GetField("IgnoreCorLibraryDuplicatedTypes").GetValue(binderFlagsType)); // Compile to assembly, throw exception if error occurred var compilation = CSharpCompilation.Create(assemblyName) .WithOptions(compilationOptions) .AddReferences(references) .AddSyntaxTrees(syntaxTrees); var emitResult = compilation.Emit(assemblyPath, pdbPath); if (!emitResult.Success) { throw new CompilationException(string.Join("\r\n", emitResult.Diagnostics.Where(d => d.WarningLevel == 0))); } }
public void Check() { Assert.IsTrue(PlatformUtils.RunningOnUnix() != PlatformUtils.RunningOnWindows()); }