File: Compilation\ClientBuildManager.cs
Project: ndp\fx\src\xsp\system\Web\System.Web.csproj (System.Web)
//------------------------------------------------------------------------------
// <copyright file="ClientBuildManager.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>                                                                
//------------------------------------------------------------------------------
 
/************************************************************************************************************/
 
 
namespace System.Web.Compilation {
 
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Remoting;
using System.Security.Permissions;
using System.Threading;
using System.Web;
using System.Web.Hosting;
using System.Web.Util;
using Debug = System.Web.Util.Debug;
 
 
// Flags that drive the behavior of precompilation
[Flags]
public enum PrecompilationFlags {
 
    Default = 0x00000000,
 
    // determines whether the deployed app will be updatable
    Updatable = 0x00000001,
 
    // determines whether the target directory can be overwritten
    OverwriteTarget = 0x00000002,
 
    // determines whether the compiler will emit debug information
    ForceDebug = 0x00000004,
 
    // determines whether the application is built clean
    Clean = 0x00000008,
 
    // determines whether the /define:CodeAnalysis flag needs to be added
    // as compilation symbol
    CodeAnalysis = 0x00000010,
 
    // determines whether to generate APTCA attribute.
    AllowPartiallyTrustedCallers = 0x00000020,
 
    // determines whether to delaySign the generate assemblies.
    DelaySign = 0x00000040,
 
    // determines whether to use fixed assembly names
    FixedNames = 0x00000080,
 
    // determines whether to skip BadImageFormatException
    IgnoreBadImageFormatException = 0x00000100,
}
 
[Serializable]
public class ClientBuildManagerParameter {
    private string _strongNameKeyFile;
    private string _strongNameKeyContainer;
    private PrecompilationFlags _precompilationFlags = PrecompilationFlags.Default;
    private List<string> _excludedVirtualPaths;
 
    public List<string> ExcludedVirtualPaths {
        get {
            if (_excludedVirtualPaths == null) {
                _excludedVirtualPaths = new List<string>();
            }
            return _excludedVirtualPaths;
        }
    }
 
    // Determines the behavior of the precompilation
    public PrecompilationFlags PrecompilationFlags {
        get { return _precompilationFlags; }
        set { _precompilationFlags = value; }
    }
 
    public string StrongNameKeyFile {
        get { return _strongNameKeyFile; }
        set { _strongNameKeyFile = value; }
    }
 
    public string StrongNameKeyContainer {
        get { return _strongNameKeyContainer; }
        set { _strongNameKeyContainer = value; }
    }
}
 
//
// This class provide access to the BuildManager outside of an IIS environment
// Instances of this class are created in the caller's App Domain.
//
// It creates and configures the new App Domain for handling BuildManager calls
// using System.Web.Hosting.ApplicationHost.CreateApplicationHost()
//
 
[PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
[PermissionSet(SecurityAction.InheritanceDemand, Unrestricted = true)]
public sealed class ClientBuildManager : MarshalByRefObject, IDisposable {
 
    private VirtualPath _virtualPath;
    private string _physicalPath;
    private string _installPath;
    private string _appId;
    private IApplicationHost _appHost;
    private string _codeGenDir;
 
    private HostingEnvironmentParameters _hostingParameters;
    private ClientBuildManagerTypeDescriptionProviderBridge _cbmTdpBridge;
 
    private WaitCallback _onAppDomainUnloadedCallback;
    private WaitCallback _onAppDomainShutdown;
    private ApplicationShutdownReason _reason;
 
    private BuildManagerHost _host;
    private Exception _hostCreationException;
    private bool _hostCreationPending;
 
    public event BuildManagerHostUnloadEventHandler AppDomainUnloaded;
 
    public event EventHandler AppDomainStarted;
 
    public event BuildManagerHostUnloadEventHandler AppDomainShutdown;
    // internal lock used for host creation.
    private object _lock = new object();
 
    // Whether to wait for the call back from the previous host unloading before creating a new one
    private bool _waitForCallBack; 
 
    private const string IISExpressPrefix = "/IISExpress/";
 
    /*
     * Creates an instance of the ClientBuildManager.
     * appPhysicalSourceDir points to the physical root of the application (e.g "c:\myapp")
     * virtualPath is the virtual path to the app root. It can be anything (e.g. "/dummy"),
     *      but ideally it should match the path later given to Cassini, in order for
     *      compilation that happens here to be reused there.
     */
 
    public ClientBuildManager(string appVirtualDir, string appPhysicalSourceDir) : 
        this(appVirtualDir, appPhysicalSourceDir,
        appPhysicalTargetDir: null, parameter: null) {
    }
 
    /*
     * Creates an instance of the PrecompilationManager.
     * appPhysicalSourceDir points to the physical root of the application (e.g "c:\myapp")
     * appVirtualDir is the virtual path to the app root. It can be anything (e.g. "/dummy"),
     *      but ideally it should match the path later given to Cassini, in order for
     *      compilation that happens here to be reused there.
     * appPhysicalTargetDir is the directory where the precompiled site is placed
     */
    public ClientBuildManager(string appVirtualDir, string appPhysicalSourceDir,
        string appPhysicalTargetDir) : this(appVirtualDir, appPhysicalSourceDir,
            appPhysicalTargetDir, parameter: null) {
    }
 
    /*
     * Creates an instance of the PrecompilationManager.
     * appPhysicalSourceDir points to the physical root of the application (e.g "c:\myapp")
     * appVirtualDir is the virtual path to the app root. It can be anything (e.g. "/dummy"),
     *      but ideally it should match the path later given to Cassini, in order for
     *      compilation that happens here to be reused there.
     * appPhysicalTargetDir is the directory where the precompiled site is placed
     * flags determines the behavior of the precompilation
     */
    public ClientBuildManager(string appVirtualDir, string appPhysicalSourceDir,
        string appPhysicalTargetDir, ClientBuildManagerParameter parameter) :
        this(appVirtualDir, appPhysicalSourceDir,
            appPhysicalTargetDir, parameter, typeDescriptionProvider: null) {
    }
 
    /*
     * Creates an instance of the PrecompilationManager.
     * appPhysicalSourceDir points to the physical root of the application (e.g "c:\myapp")
     * appVirtualDir is the virtual path to the app root. It can be anything (e.g. "/dummy"),
     *      but ideally it should match the path later given to Cassini, in order for
     *      compilation that happens here to be reused there.
     * appPhysicalTargetDir is the directory where the precompiled site is placed
     * typeDescriptionProvider is the provider used for retrieving type 
     * information for multi-targeting 
     */
    public ClientBuildManager(string appVirtualDir, string appPhysicalSourceDir,
        string appPhysicalTargetDir, ClientBuildManagerParameter parameter,
        TypeDescriptionProvider typeDescriptionProvider) {
 
        if (parameter == null) {
            parameter = new ClientBuildManagerParameter();
        }
 
        InitializeCBMTDPBridge(typeDescriptionProvider);
 
        // Always build clean in precompilation for deployment mode, 
        // since building incrementally raises all kind of issues (VSWhidbey 382954).
        if (!String.IsNullOrEmpty(appPhysicalTargetDir)) {
            parameter.PrecompilationFlags |= PrecompilationFlags.Clean;
        }
 
        _hostingParameters = new HostingEnvironmentParameters();
        _hostingParameters.HostingFlags = HostingEnvironmentFlags.DontCallAppInitialize |
                                          HostingEnvironmentFlags.ClientBuildManager;
        _hostingParameters.ClientBuildManagerParameter = parameter;
        _hostingParameters.PrecompilationTargetPhysicalDirectory = appPhysicalTargetDir;
        if (typeDescriptionProvider != null) {
            _hostingParameters.HostingFlags |= HostingEnvironmentFlags.SupportsMultiTargeting;
        }
 
        // Make sure the app virtual dir starts with /
        if (appVirtualDir[0] != '/')
            appVirtualDir = "/" + appVirtualDir;
 
        if (appPhysicalSourceDir == null
            && appVirtualDir.StartsWith(IISExpressPrefix, StringComparison.OrdinalIgnoreCase)
            && appVirtualDir.Length > IISExpressPrefix.Length) {
            // appVirtualDir should have the form "/IISExpress/<version>/LM/W3SVC/",
            // and we will try to extract the version.  The version will be validated
            // when it is passed to IISVersionHelper..ctor.
            int endSlash = appVirtualDir.IndexOf('/', IISExpressPrefix.Length);
            if (endSlash > 0) {
                _hostingParameters.IISExpressVersion = appVirtualDir.Substring(IISExpressPrefix.Length, endSlash - IISExpressPrefix.Length);
                appVirtualDir = appVirtualDir.Substring(endSlash);
            }
        }
 
        Initialize(VirtualPath.CreateNonRelative(appVirtualDir), appPhysicalSourceDir);
    }
 
    /*
     * returns the codegendir used by runtime appdomain
     */
    public string CodeGenDir {
        get {
            if (_codeGenDir == null) {
                EnsureHostCreated();
                _codeGenDir = _host.CodeGenDir;
            }
 
            return _codeGenDir;
        }
    }
 
    /*
     * Indicates whether the host is created.
     */
 
    public bool IsHostCreated {
        get {
            return _host != null;
        }
    }
 
    /*
     * Create an object in the runtime appdomain
     */
 
    public IRegisteredObject CreateObject(Type type, bool failIfExists) {
        if (type == null) {
            throw new ArgumentNullException("type");
        }
 
        EnsureHostCreated();
        Debug.Assert(_appId != null);
        Debug.Assert(_appHost != null);
 
        _host.RegisterAssembly(type.Assembly.FullName, type.Assembly.Location);
 
        ApplicationManager appManager = ApplicationManager.GetApplicationManager();
        return appManager.CreateObjectInternal(_appId, type, _appHost, failIfExists, _hostingParameters);
    }
 
    /*
     * Return the list of directories that would cause appdomain shutdown.
     */
    public string[] GetAppDomainShutdownDirectories() {
        Debug.Trace("CBM", "GetAppDomainShutdownDirectories");
 
        return FileChangesMonitor.s_dirsToMonitor;
    }
 
    /*
     * Makes sure that all the top level files are compiled (code, global.asax, ...)
     */
 
    public void CompileApplicationDependencies() {
        Debug.Trace("CBM", "CompileApplicationDependencies");
 
        EnsureHostCreated();
 
        _host.CompileApplicationDependencies();
    }
 
 
    public IDictionary GetBrowserDefinitions() {
        Debug.Trace("CBM", "GetBrowserDefinitions");
 
        EnsureHostCreated();
 
        return _host.GetBrowserDefinitions();
    }
 
    /*
     * Returns the physical path of the generated file corresponding to the virtual directory.
     * Note the virtualPath needs to use this format:
     * "/[appname]/App_WebReferences/{[subDir]/}"
     */
    public string GetGeneratedSourceFile(string virtualPath) {
        Debug.Trace("CBM", "GetGeneratedSourceFile " + virtualPath);
 
        if (virtualPath == null) {
            throw new ArgumentNullException("virtualPath");
        }
 
        EnsureHostCreated();
 
        return _host.GetGeneratedSourceFile(VirtualPath.CreateTrailingSlash(virtualPath));
    }
 
    /*
    * Returns the virtual path of the corresponding generated file.
    * Note the filepath needs to be a full path.
    */
    public string GetGeneratedFileVirtualPath(string filePath) {
        Debug.Trace("CBM", "GetGeneratedFileVirtualPath " + filePath);
 
        if (filePath == null) {
            throw new ArgumentNullException("filePath");
        }
 
        EnsureHostCreated();
 
        return _host.GetGeneratedFileVirtualPath(filePath);
    }
    /*
     * Returns an array of the virtual paths to all the code directories in the app thru the hosted appdomain
     */
 
    public string[] GetVirtualCodeDirectories() {
        Debug.Trace("CBM", "GetHostedVirtualCodeDirectories");
 
        EnsureHostCreated();
 
        return _host.GetVirtualCodeDirectories();
    }
 
    /*
     * Returns an array of the assemblies defined in the bin and assembly reference config section
     */
 
    public String[] GetTopLevelAssemblyReferences(string virtualPath) {
        Debug.Trace("CBM", "GetHostedVirtualCodeDirectories");
 
        if (virtualPath == null) {
            throw new ArgumentNullException("virtualPath");
        }
 
        EnsureHostCreated();
 
        return _host.GetTopLevelAssemblyReferences(VirtualPath.Create(virtualPath));
    }
 
    /*
     * Returns the compiler type and parameters that need to be used to build
     * a given code directory.  Also, returns the directory containing all the code
     * files generated from non-code files in the code directory (e.g. wsdl files)
     */
 
    public void GetCodeDirectoryInformation(string virtualCodeDir,
        out Type codeDomProviderType, out CompilerParameters compilerParameters,
        out string generatedFilesDir) {
        Debug.Trace("CBM", "GetCodeDirectoryInformation " + virtualCodeDir);
 
        if (virtualCodeDir == null) {
            throw new ArgumentNullException("virtualCodeDir");
        }
 
        EnsureHostCreated();
 
        _host.GetCodeDirectoryInformation(VirtualPath.CreateTrailingSlash(virtualCodeDir),
            out codeDomProviderType, out compilerParameters, out generatedFilesDir);
 
        Debug.Trace("CBM", "GetCodeDirectoryInformation " + virtualCodeDir + " end");
    }
 
    /*
     * Returns the compiler type and parameters that need to be used to build
     * a given file.
     */
 
    public void GetCompilerParameters(string virtualPath,
        out Type codeDomProviderType, out CompilerParameters compilerParameters) {
        Debug.Trace("CBM", "GetCompilerParameters " + virtualPath);
 
        if (virtualPath == null) {
            throw new ArgumentNullException("virtualPath");
        }
 
        EnsureHostCreated();
 
        _host.GetCompilerParams(VirtualPath.Create(virtualPath), out codeDomProviderType, out compilerParameters);
    }
 
    /*
     * Returns the codedom tree and the compiler type/param for a given file.
     */
 
    public CodeCompileUnit GenerateCodeCompileUnit(
        string virtualPath, out Type codeDomProviderType,
        out CompilerParameters compilerParameters, out IDictionary linePragmasTable) {
        Debug.Trace("CBM", "GenerateCodeCompileUnit " + virtualPath);
 
        return GenerateCodeCompileUnit(virtualPath, null, 
            out codeDomProviderType, out compilerParameters, out linePragmasTable);
    }
 
 
    public CodeCompileUnit GenerateCodeCompileUnit(
        string virtualPath, String virtualFileString, out Type codeDomProviderType,
        out CompilerParameters compilerParameters, out IDictionary linePragmasTable) {
        Debug.Trace("CBM", "GenerateCodeCompileUnit " + virtualPath);
 
        if (virtualPath == null) {
            throw new ArgumentNullException("virtualPath");
        }
 
        EnsureHostCreated();
 
        return _host.GenerateCodeCompileUnit(VirtualPath.Create(virtualPath), virtualFileString,
            out codeDomProviderType, out compilerParameters, out linePragmasTable);
    }
 
    public string GenerateCode(
        string virtualPath, String virtualFileString, out IDictionary linePragmasTable) {
        Debug.Trace("CBM", "GenerateCode " + virtualPath);
 
        if (virtualPath == null) {
            throw new ArgumentNullException("virtualPath");
        }
 
        EnsureHostCreated();
 
        return _host.GenerateCode(VirtualPath.Create(virtualPath), virtualFileString, out linePragmasTable);
    }
 
    /*
     * Returns the compiled type for an input file
     */
 
    public Type GetCompiledType(string virtualPath) {
        Debug.Trace("CBM", "GetCompiledType " + virtualPath);
 
        if (virtualPath == null) {
            throw new ArgumentNullException("virtualPath");
        }
 
        EnsureHostCreated();
 
        string[] typeAndAsemblyName = _host.GetCompiledTypeAndAssemblyName(VirtualPath.Create(virtualPath), null);
        if (typeAndAsemblyName == null)
            return null;
 
        Assembly a = Assembly.LoadFrom(typeAndAsemblyName[1]);
        Type t = a.GetType(typeAndAsemblyName[0]);
        return t;
    }
 
    /*
     * Compile a file
     */
    public void CompileFile(string virtualPath) {
        CompileFile(virtualPath, null);
    }
 
    public void CompileFile(string virtualPath, ClientBuildManagerCallback callback) {
        Debug.Trace("CBM", "CompileFile " + virtualPath);
 
        if (virtualPath == null) {
            throw new ArgumentNullException("virtualPath");
        }
 
        try {
            EnsureHostCreated();
            _host.GetCompiledTypeAndAssemblyName(VirtualPath.Create(virtualPath), callback);
        }
        finally {
            // DevDiv 180798. We are returning null in ClientBuildManagerCallback.InitializeLifetimeService,
            // so we need to manually disconnect the instance so that it will be released.
            if (callback != null) {
                RemotingServices.Disconnect(callback);
            }
        }
    }
 
    /*
     * Indicates whether an assembly is a code assembly.
     */
    public bool IsCodeAssembly(string assemblyName) {
        Debug.Trace("CBM", "IsCodeAssembly " + assemblyName);
 
        if (assemblyName == null) {
            throw new ArgumentNullException("assemblyName");
        }
 
        // 
 
        EnsureHostCreated();
        bool result = _host.IsCodeAssembly(assemblyName);
 
        Debug.Trace("CBM", "IsCodeAssembly " + result.ToString());
        return result;
    }
 
 
    public bool Unload() {
        Debug.Trace("CBM", "Unload");
 
        BuildManagerHost host = _host;
        if (host != null) {
            _host = null;
            return host.UnloadAppDomain();
        }
 
        return false;
    }
 
    /*
     * Precompile an application 
     */
    public void PrecompileApplication() {
        PrecompileApplication(null);
    }
 
    /*
     * Precompile an application with callback support
     */
    public void PrecompileApplication(ClientBuildManagerCallback callback) {
        PrecompileApplication(callback, false);
    }
 
    public void PrecompileApplication(ClientBuildManagerCallback callback, bool forceCleanBuild) {
        Debug.Trace("CBM", "PrecompileApplication");
 
        PrecompilationFlags savedFlags = _hostingParameters.ClientBuildManagerParameter.PrecompilationFlags;
 
        if (forceCleanBuild) {
 
            // If there was a previous host, it will be unloaded by CBM and we will wait for the callback.
            // If there was no previous host, we don't do any waiting.
            // DevDiv 46290
            _waitForCallBack = _host != null;
 
            Debug.Trace("CBM", "Started Unload");
            // Unload the existing appdomain so the new one will be created with the clean flag
            Unload();
 
            _hostingParameters.ClientBuildManagerParameter.PrecompilationFlags = 
                savedFlags | PrecompilationFlags.Clean;
 
            WaitForCallBack();
        }
 
        try {
            EnsureHostCreated();
            _host.PrecompileApp(callback, _hostingParameters.ClientBuildManagerParameter.ExcludedVirtualPaths);
        }
        finally {
            if (forceCleanBuild) {
                // Revert precompilationFlags
                _hostingParameters.ClientBuildManagerParameter.PrecompilationFlags = savedFlags;
            }
            // DevDiv 180798. We are returning null in ClientBuildManagerCallback.InitializeLifetimeService,
            // so we need to manually disconnect the instance so that it will be released.
            if (callback != null) {
                RemotingServices.Disconnect(callback);
            }
        }
    }
 
    // _waitForCallBack is set to false in OnAppDomainUnloaded.
    // This method waits until it is set to false before continuing, so that
    // we do not run into a concurrency issue where _host could be set to null.
    // DevDiv 46290
    private void WaitForCallBack() {
        Debug.Trace("CBM", "WaitForCallBack");
        int waited = 0;
        while (_waitForCallBack && waited <= 50) {
            Thread.Sleep(200);
            waited++;
        }
        if (_waitForCallBack) {
            Debug.Trace("CBM", "timeout while waiting for callback");
        }
        else {
            Debug.Trace("CBM", "callback received before timeout");
        }
    }
 
    public override Object InitializeLifetimeService() {
        return null; // never expire lease
    }
 
    internal void Initialize(VirtualPath virtualPath, string physicalPath) {
        Debug.Trace("CBM", "Initialize");
 
        _virtualPath = virtualPath;
 
        _physicalPath = FileUtil.FixUpPhysicalDirectory(physicalPath);
 
        _onAppDomainUnloadedCallback = new WaitCallback(OnAppDomainUnloadedCallback);
        _onAppDomainShutdown = new WaitCallback(OnAppDomainShutdownCallback);
 
        _installPath = RuntimeEnvironment.GetRuntimeDirectory();
 
        // Do not create host during intialization. It will be done on demand.
        //CreateHost();
    }
 
    private void EnsureHostCreated() {
 
        if (_host == null) {
            lock (_lock) {
                // Create the host if necessary
                if (_host == null) {
                    CreateHost();
                    Debug.Trace("CBM", "EnsureHostCreated: after CreateHost()");
                }
            }
        }
 
        // If an exception happened during host creation, rethrow it
        if (_hostCreationException != null) {
            Debug.Trace("CBM", "EnsureHostCreated: failed. " + _hostCreationException);
 
            // We need to wrap it in a new exception, otherwise we lose the original stack.
            throw new HttpException(_hostCreationException.Message,
                _hostCreationException);
        }
    }
 
    private void CreateHost() {
        Debug.Trace("CBM", "CreateHost");
        Debug.Assert(_host == null);
 
        Debug.Assert(!_hostCreationPending, "CreateHost: creation already pending");
 
        _hostCreationPending = true;
 
        // Use a local to avoid having a partially created _host
        BuildManagerHost host = null;
 
        try {
            string appId;
            IApplicationHost appHost;
 
            ApplicationManager appManager = ApplicationManager.GetApplicationManager();
 
            host = (BuildManagerHost) appManager.CreateObjectWithDefaultAppHostAndAppId(
                _physicalPath, _virtualPath,
                typeof(BuildManagerHost), false /*failIfExists*/, 
                _hostingParameters, out appId, out appHost);
 
            // host appdomain cannot be unloaded during creation.
            host.AddPendingCall();
 
            host.Configure(this);
 
            _host = host;
            _appId = appId;
            _appHost = appHost;
 
            _hostCreationException = _host.InitializationException;
        }
        catch (Exception e) {
            // If an exception happens, keep track of it
            _hostCreationException = e;
 
            // Even though the host initialization failed, keep track of it so subsequent
            // request will see the error
            _host = host;
        }
        finally {
            _hostCreationPending = false;
 
            if (host != null) {
                // Notify the client that the host is ready
                if (AppDomainStarted != null) {
                    AppDomainStarted(this, EventArgs.Empty);
                }
 
                // The host can be unloaded safely now.
                host.RemovePendingCall();
            }
        }
 
        Debug.Trace("CBM", "CreateHost LEAVE");
    }
 
    // Called by BuildManagerHost when the ASP appdomain is unloaded
    internal void OnAppDomainUnloaded(ApplicationShutdownReason reason) {
        Debug.Trace("CBM", "OnAppDomainUnloaded " + reason.ToString());
 
        _reason = reason;
        _waitForCallBack = false;
 
        // Don't do anything that can be slow here.  Instead queue in a worker thread
        ThreadPool.QueueUserWorkItem(_onAppDomainUnloadedCallback);
    }
 
    internal void ResetHost() {
        lock (_lock) {
            // Though _appId and _appHost are created along with _host,
            // we need not reset those here as they always correspond to 
            // default app id and app host.
            _host = null;
            _hostCreationException = null;
        }
    }
 
    [PermissionSet(SecurityAction.Assert, Unrestricted = true)]
    private void OnAppDomainUnloadedCallback(Object unused) {
        Debug.Trace("CBM", "OnAppDomainUnloadedCallback");
 
        // Notify the client that the appdomain is unloaded
        if (AppDomainUnloaded != null) {
            AppDomainUnloaded(this, new BuildManagerHostUnloadEventArgs(_reason));
        }
    }
 
    [PermissionSet(SecurityAction.Assert, Unrestricted = true)]
    private void OnAppDomainShutdownCallback(Object o) {
        if (AppDomainShutdown != null) {
            AppDomainShutdown(this, new BuildManagerHostUnloadEventArgs((ApplicationShutdownReason)o));
        }
    }
 
    internal void OnAppDomainShutdown(ApplicationShutdownReason reason) {
        // Don't do anything that can be slow here. Instead queue in a worker thread
        ThreadPool.QueueUserWorkItem(_onAppDomainShutdown, reason);
    }
 
    private void InitializeCBMTDPBridge(TypeDescriptionProvider typeDescriptionProvider) {
        if (typeDescriptionProvider == null){
            return;
        }
        _cbmTdpBridge = new ClientBuildManagerTypeDescriptionProviderBridge(typeDescriptionProvider);
    }
 
    internal ClientBuildManagerTypeDescriptionProviderBridge CBMTypeDescriptionProviderBridge {
        get {
            return _cbmTdpBridge;
        }
    }
 
    #region IDisposable
    //Dispose the runtime appdomain properly when CBM is disposed
    void IDisposable.Dispose() {
        Unload();
    }
    #endregion
 
}
 
 
[PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
[PermissionSet(SecurityAction.InheritanceDemand, Unrestricted = true)]
public class BuildManagerHostUnloadEventArgs : EventArgs {
    ApplicationShutdownReason _reason;
 
    public BuildManagerHostUnloadEventArgs(ApplicationShutdownReason reason) {
        _reason = reason;
    }
 
    // Get the reason for the hosted appdomain shutdown
 
    public ApplicationShutdownReason Reason { get { return _reason; } }
}
 
 
public delegate void BuildManagerHostUnloadEventHandler(object sender, BuildManagerHostUnloadEventArgs e);
 
/*
 * Type of the entries in the table returned by GenerateCodeCompileUnit
 */
 
[Serializable]
public sealed class LinePragmaCodeInfo {
 
    public LinePragmaCodeInfo() {
    }
 
    public LinePragmaCodeInfo(int startLine, int startColumn, int startGeneratedColumn, int codeLength, bool isCodeNugget) {
        this._startLine = startLine;
        this._startColumn = startColumn;
        this._startGeneratedColumn = startGeneratedColumn;
        this._codeLength = codeLength;
        this._isCodeNugget = isCodeNugget;
    }
 
    // Starting line in ASPX file
    internal int _startLine;
 
    public int StartLine { get { return _startLine; } }
 
    // Starting column in the ASPX file
    internal int _startColumn;
 
    public int StartColumn { get { return _startColumn; } }
 
    // Starting column in the generated source file (assuming no indentations are used)
    internal int _startGeneratedColumn;
 
    public int StartGeneratedColumn { get { return _startGeneratedColumn; } }
 
    // Length of the code snippet
    internal int _codeLength;
 
    public int CodeLength { get { return _codeLength; } }
 
    // Whether the script block is a nugget.
    internal bool _isCodeNugget;
 
    public bool IsCodeNugget { get { return _isCodeNugget; } }
}
 
}