// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. using System.CodeDom; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Web.Razor.Generator; using System.Web.Razor.Parser; namespace System.Web.Razor { /// /// Defines the environment in which a Razor template will live /// /// /// The host defines the following things: /// * What method names will be used for rendering markup, expressions etc. For example "Write", "WriteLiteral" /// * The namespace imports to be added to every page generated via this host /// * The default Base Class to inherit the generated class from /// * The default Class Name and Namespace for the generated class (can be overridden by parameters in RazorTemplateEngine.GeneratedCode) /// * The language of the code in a Razor page /// * The markup, code parsers and code generators to use (the system will select defaults, but a Host gets a change to augment them) /// ** See DecorateNNN methods /// * Additional code to add to the generated code (see PostProcessGeneratedCode) /// public class RazorEngineHost { internal const string InternalDefaultClassName = "__CompiledTemplate"; internal const string InternalDefaultNamespace = "Razor"; private bool _instrumentationActive = false; private Func _markupParserFactory; [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "The code path is safe, it is a property setter and not dependent on other state")] protected RazorEngineHost() { GeneratedClassContext = GeneratedClassContext.Default; NamespaceImports = new HashSet(); DesignTimeMode = false; DefaultNamespace = InternalDefaultNamespace; DefaultClassName = InternalDefaultClassName; EnableInstrumentation = false; } /// /// Creates a host which uses the specified code language and the HTML markup language /// /// The code language to use public RazorEngineHost(RazorCodeLanguage codeLanguage) : this(codeLanguage, () => new HtmlMarkupParser()) { } [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "The code path is safe, it is a property setter and not dependent on other state")] public RazorEngineHost(RazorCodeLanguage codeLanguage, Func markupParserFactory) : this() { if (codeLanguage == null) { throw new ArgumentNullException("codeLanguage"); } if (markupParserFactory == null) { throw new ArgumentNullException("markupParserFactory"); } CodeLanguage = codeLanguage; _markupParserFactory = markupParserFactory; } /// /// Details about the methods and types that should be used to generate code for Razor constructs /// public virtual GeneratedClassContext GeneratedClassContext { get; set; } /// /// A list of namespaces to import in the generated file /// public virtual ISet NamespaceImports { get; private set; } /// /// The base-class of the generated class /// public virtual string DefaultBaseClass { get; set; } /// /// Indiciates if the parser and code generator should run in design-time mode /// public virtual bool DesignTimeMode { get; set; } /// /// The name of the generated class /// public virtual string DefaultClassName { get; set; } /// /// The namespace which will contain the generated class /// public virtual string DefaultNamespace { get; set; } /// /// Boolean indicating if helper methods should be instance methods or static methods /// public virtual bool StaticHelpers { get; set; } /// /// The language of the code within the Razor template. /// public virtual RazorCodeLanguage CodeLanguage { get; protected set; } /// /// Boolean indicating if instrumentation code should be injected into the output page /// public virtual bool EnableInstrumentation { // Always disable instrumentation in DesignTimeMode. get { return !DesignTimeMode && _instrumentationActive; } set { _instrumentationActive = value; } } /// /// Gets or sets the path to use for this document when generating Instrumentation calls /// public virtual string InstrumentedSourceFilePath { get; set; } /// /// Constructs the markup parser. Must return a new instance on EVERY call to ensure thread-safety /// public virtual ParserBase CreateMarkupParser() { if (_markupParserFactory != null) { return _markupParserFactory(); } return null; } /// /// Gets an instance of the code parser and is provided an opportunity to decorate or replace it /// /// The code parser /// Either the same code parser, after modifications, or a different code parser public virtual ParserBase DecorateCodeParser(ParserBase incomingCodeParser) { if (incomingCodeParser == null) { throw new ArgumentNullException("incomingCodeParser"); } return incomingCodeParser; } /// /// Gets an instance of the markup parser and is provided an opportunity to decorate or replace it /// /// The markup parser /// Either the same markup parser, after modifications, or a different markup parser public virtual ParserBase DecorateMarkupParser(ParserBase incomingMarkupParser) { if (incomingMarkupParser == null) { throw new ArgumentNullException("incomingMarkupParser"); } return incomingMarkupParser; } /// /// Gets an instance of the code generator and is provided an opportunity to decorate or replace it /// /// The code generator /// Either the same code generator, after modifications, or a different code generator public virtual RazorCodeGenerator DecorateCodeGenerator(RazorCodeGenerator incomingCodeGenerator) { if (incomingCodeGenerator == null) { throw new ArgumentNullException("incomingCodeGenerator"); } return incomingCodeGenerator; } /// /// Gets the important CodeDOM nodes generated by the code generator and has a chance to add to them. /// /// /// All the other parameter values can be located by traversing tree in the codeCompileUnit node, they /// are simply provided for convenience /// /// The current . public virtual void PostProcessGeneratedCode(CodeGeneratorContext context) { #pragma warning disable 0618 PostProcessGeneratedCode(context.CompileUnit, context.Namespace, context.GeneratedClass, context.TargetMethod); #pragma warning restore 0618 } [Obsolete("This method is obsolete, use the override which takes a CodeGeneratorContext instead")] public virtual void PostProcessGeneratedCode(CodeCompileUnit codeCompileUnit, CodeNamespace generatedNamespace, CodeTypeDeclaration generatedClass, CodeMemberMethod executeMethod) { if (codeCompileUnit == null) { throw new ArgumentNullException("codeCompileUnit"); } if (generatedNamespace == null) { throw new ArgumentNullException("generatedNamespace"); } if (generatedClass == null) { throw new ArgumentNullException("generatedClass"); } if (executeMethod == null) { throw new ArgumentNullException("executeMethod"); } } } }