// 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");
}
}
}
}