예제 #1
0
        /// <summary>
        /// Creates an engine with the specified application state, configuration, and service provider.
        /// </summary>
        /// <param name="applicationState">The state of the application (or <c>null</c> for an empty application state).</param>
        /// <param name="serviceCollection">The service collection (or <c>null</c> for an empty default service collection).</param>
        /// <param name="configuration">The application configuration.</param>
        /// <param name="settings">Settings that should override configuration values.</param>
        /// <param name="classCatalog">A class catalog of all assemblies in scope.</param>
        public Engine(
            ApplicationState applicationState,
            IServiceCollection serviceCollection,
            IConfiguration configuration,
            IEnumerable <KeyValuePair <string, object> > settings,
            ClassCatalog classCatalog)
        {
            _pipelines       = new PipelineCollection(this);
            ApplicationState = applicationState ?? new ApplicationState(null, null, null);
            ClassCatalog     = classCatalog ?? new ClassCatalog();
            ClassCatalog.Populate();
            ScriptHelper = new ScriptHelper(this);
            Settings     = new ConfigurationSettings(
                this,
                configuration ?? new ConfigurationRoot(Array.Empty <IConfigurationProvider>()),
                settings);
            _serviceScope             = GetServiceScope(serviceCollection);
            _logger                   = Services.GetRequiredService <ILogger <Engine> >();
            DocumentFactory           = new DocumentFactory(this, Settings);
            _diagnosticsTraceListener = new DiagnosticsTraceListener(_logger);
            System.Diagnostics.Trace.Listeners.Add(_diagnosticsTraceListener);

            // Add the service-based pipelines as late as possible so other services have been configured
            AddServicePipelines();
        }
예제 #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Configurator"/> class. This overload
 /// allows passing in a <see cref="Preprocessor"/> that can be reused and pre-configured
 /// with directives not sourced from the script.
 /// </summary>
 /// <param name="engine">The engine to configure.</param>
 /// <param name="preprocessor">The preprocessor.</param>
 public Configurator(Engine engine, Preprocessor preprocessor)
 {
     _engine           = engine;
     _preprocessor     = preprocessor;
     _assemblyResolver = new AssemblyResolver(_scriptManager);
     AssemblyLoader    = new AssemblyLoader(engine.FileSystem, _assemblyResolver);
     PackageInstaller  = new PackageInstaller(engine.FileSystem, AssemblyLoader);
     ClassCatalog      = new ClassCatalog();
     engine.Namespaces.Add(typeof(ScriptBase).Namespace);
 }
예제 #3
0
 private void CatalogClasses()
 {
     System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew();
     using (Trace.WithIndent().Information("Cataloging classes"))
     {
         ClassCatalog.CatalogTypes(AssemblyLoader.DirectAssemblies);
         stopwatch.Stop();
         Trace.Information($"Classes cataloged in {stopwatch.ElapsedMilliseconds} ms");
     }
 }
예제 #4
0
        private void AddNamespaces()
        {
            // Add all Wyam.Common namespaces
            _engine.Namespaces.AddRange(typeof(IModule).Assembly.GetTypes()
                                        .Where(x => !string.IsNullOrWhiteSpace(x.Namespace))
                                        .Select(x => x.Namespace)
                                        .Distinct());

            // Add all module namespaces
            _engine.Namespaces.AddRange(ClassCatalog.GetClasses <IModule>().Select(x => x.Namespace));
        }
예제 #5
0
파일: Configurator.cs 프로젝트: ibebbs/Wyam
        /// <summary>
        /// Initializes a new instance of the <see cref="Configurator"/> class. This overload
        /// allows passing in a <see cref="Preprocessor"/> that can be reused and pre-configured
        /// with directives not sourced from the script.
        /// </summary>
        /// <param name="engine">The engine to configure.</param>
        /// <param name="preprocessor">The preprocessor.</param>
        public Configurator(Engine engine, Preprocessor preprocessor)
        {
            _engine = engine;
            _preprocessor = preprocessor;
            _assemblyResolver = new AssemblyResolver(_scriptManager); 
            AssemblyLoader = new AssemblyLoader(engine.FileSystem, engine.Assemblies, _assemblyResolver);
            PackageInstaller = new PackageInstaller(engine.FileSystem, AssemblyLoader);
            ClassCatalog = new ClassCatalog();

            // Add this namespace and assembly
            engine.Namespaces.Add(typeof(ScriptBase).Namespace);
            engine.Assemblies.Add(typeof(ScriptBase).Assembly);
        }
        private void AddShortcodes()
        {
            foreach (Type shortcode in ClassCatalog.GetClasses <IShortcode>())
            {
                _engine.Shortcodes.Add(shortcode);

                // Special case for the meta shortcode to register with the name "="
                if (shortcode.Equals(typeof(Core.Shortcodes.Metadata.Meta)))
                {
                    _engine.Shortcodes.Add("=", shortcode);
                }
            }
        }
예제 #7
0
        private void AddNamespaces()
        {
            // Add all Wyam.Common namespaces
            // the JetBrains.Profiler filter is needed due to DotTrace dynamically
            // adding a reference to that assembly when running under its profiler. We want
            // to exclude it.
            _engine.Namespaces.AddRange(typeof(IModule).Assembly.GetTypes()
                                        .Where(x => !string.IsNullOrWhiteSpace(x.Namespace) && !x.Namespace.StartsWith("JetBrains.Profiler"))
                                        .Select(x => x.Namespace)
                                        .Distinct());

            // Add all module namespaces
            _engine.Namespaces.AddRange(ClassCatalog.GetClasses <IModule>().Select(x => x.Namespace));
        }
예제 #8
0
 private void ApplyRecipe()
 {
     if (Recipe == null && !string.IsNullOrEmpty(RecipeName))
     {
         Recipe = ClassCatalog.GetInstance <IRecipe>(RecipeName, true);
         if (Recipe == null)
         {
             throw new Exception($"The recipe \"{RecipeName}\" could not be found");
         }
     }
     if (Recipe != null)
     {
         _engine.Namespaces.Add(Recipe.GetType().Namespace);  // Add the recipe namespace so it's available to modules
         Recipe.Apply(_engine);
     }
 }
예제 #9
0
        private void Evaluate(string code)
        {
            if (string.IsNullOrEmpty(code))
            {
                return;
            }

            Stopwatch stopwatch = Stopwatch.StartNew();

            using (Trace.WithIndent().Information("Evaluating configuration script"))
            {
                CacheManager cacheManager = new CacheManager(_engine, _scriptManager, ConfigDllPath, ConfigHashPath, OutputScriptPath);
                cacheManager.EvaluateCode(code, ClassCatalog.GetClasses <IModule>().ToList(), OutputScript, IgnoreConfigHash, NoOutputConfigAssembly);

                stopwatch.Stop();
                Trace.Information($"Evaluated configuration script in {stopwatch.ElapsedMilliseconds} ms");
            }
        }
예제 #10
0
        private void Evaluate(string code)
        {
            if (string.IsNullOrEmpty(code))
            {
                return;
            }

            System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew();
            using (Trace.WithIndent().Information("Evaluating configuration script"))
            {
                _scriptManager.Create(code, ClassCatalog.GetClasses <IModule>().ToList(), _engine.Namespaces);
                WriteScript(_scriptManager.Code);
                _scriptManager.Compile(AppDomain.CurrentDomain.GetAssemblies());
                _engine.DynamicAssemblies.Add(_scriptManager.RawAssembly);
                _scriptManager.Evaluate(_engine);
                stopwatch.Stop();
                Trace.Information($"Evaluated configuration script in {stopwatch.ElapsedMilliseconds} ms");
            }
        }
예제 #11
0
 private void AddFileProviders()
 {
     foreach (IFileProvider fileProvider in ClassCatalog.GetInstances <IFileProvider>())
     {
         string scheme = fileProvider.GetType().Name.ToLowerInvariant();
         if (scheme.EndsWith("fileprovider"))
         {
             scheme = scheme.Substring(0, scheme.Length - 12);
         }
         if (scheme.EndsWith("provider"))
         {
             scheme = scheme.Substring(0, 8);
         }
         if (!string.IsNullOrEmpty(scheme))
         {
             _engine.FileSystem.FileProviders.Add(scheme, fileProvider);
         }
     }
 }
        /// <summary>
        /// Adds all services required for the <see cref="RenderRazor"/> module.
        /// </summary>
        /// <param name="serviceCollection">The service collection to register services in.</param>
        /// <param name="fileSystem">The file system or <c>null</c> to skip.</param>
        /// <param name="classCatalog">An existing class catalog or <c>null</c> to scan assemblies during registration.</param>
        /// <returns>The service collection.</returns>
        public static IServiceCollection AddRazor(this IServiceCollection serviceCollection, IReadOnlyFileSystem fileSystem, ClassCatalog classCatalog = null)
        {
            // Register the file system if we're not expecting one from an engine
            if (fileSystem != null)
            {
                serviceCollection.TryAddSingleton(fileSystem);
            }

            // Register some of our own types if not already registered
            serviceCollection.TryAddSingleton <Microsoft.Extensions.FileProviders.IFileProvider, FileSystemFileProvider>();
            serviceCollection.TryAddSingleton <DiagnosticSource, SilentDiagnosticSource>();
            serviceCollection.TryAddSingleton(new DiagnosticListener("Razor"));
            serviceCollection.TryAddSingleton <IWebHostEnvironment, HostEnvironment>();
            serviceCollection.TryAddSingleton <ObjectPoolProvider, DefaultObjectPoolProvider>();
            serviceCollection.TryAddSingleton <StatiqRazorProjectFileSystem>();
            serviceCollection.TryAddSingleton <RazorProjectFileSystem, StatiqRazorProjectFileSystem>();

            // Register the view location expander if not already registered
            serviceCollection.Configure <RazorViewEngineOptions>(x =>
            {
                if (!x.ViewLocationExpanders.OfType <ViewLocationExpander>().Any())
                {
                    x.ViewLocationExpanders.Add(new ViewLocationExpander());
                }
            });

            // Add the default services _after_ adding our own
            // (most default registration use .TryAdd...() so they skip already registered types)
            IMvcCoreBuilder builder = serviceCollection
                                      .AddMvcCore()
                                      .AddRazorViewEngine()
                                      .AddRazorRuntimeCompilation();

            // Add all loaded assemblies
            CompilationReferencesProvider referencesProvider = new CompilationReferencesProvider();

            referencesProvider.Assemblies.AddRange((classCatalog ?? new ClassCatalog()).GetAssemblies());

            // And a couple needed assemblies that might not be loaded in the AppDomain yet
            referencesProvider.Assemblies.Add(typeof(IHtmlContent).Assembly);
            referencesProvider.Assemblies.Add(Assembly.Load(new AssemblyName("Microsoft.CSharp")));

            // Add the reference provider as an ApplicationPart
            builder.ConfigureApplicationPartManager(x => x.ApplicationParts.Add(referencesProvider));

            return(serviceCollection);
        }