PartialClassGenerationTask.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / XamlBuildTask / Microsoft / Build / Tasks / Xaml / PartialClassGenerationTask.cs / 1606072 / PartialClassGenerationTask.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace Microsoft.Build.Tasks.Xaml 
{
    using System; 
    using System.Collections.Generic; 
    using Microsoft.Build.Framework;
    using Microsoft.Build.Utilities; 
    using System.Reflection;
    using System.Runtime;
    using System.IO;
    using System.Threading; 

    [Fx.Tag.XamlVisible(true)] 
    public class PartialClassGenerationTask : Task 
    {
        const string DefaultGeneratedSourceExtension = "g"; 
        List generatedResources = new List();
        List generatedCodeFiles = new List();

        public PartialClassGenerationTask() 
        {
            this.GeneratedSourceExtension = DefaultGeneratedSourceExtension; 
        } 

        [Fx.Tag.KnownXamlExternal] 
        public ITaskItem[] ApplicationMarkup { get; set; }

        public string AssemblyName
        { get; set; } 

        public string[] KnownReferencePaths { get; set; } 
 
        [Fx.Tag.KnownXamlExternal]
        [Output] 
        public ITaskItem[] GeneratedResources
        {
            get
            { 
                return generatedResources.ToArray();
            } 
 
            set
            { 
                generatedResources = new List(value);
            }
        }
 
        [Fx.Tag.KnownXamlExternal]
        [Output] 
        public ITaskItem[] GeneratedCodeFiles 
        {
            get 
            {
                return generatedCodeFiles.ToArray();
            }
 
            set
            { 
                generatedCodeFiles = new List(value); 
            }
        } 

        public string GeneratedSourceExtension
        { get; set; }
 
        [Required]
        public string Language 
        { get; set; } 

        [Required] 
        public string OutputPath
        { get; set; }

        [Fx.Tag.KnownXamlExternal] 
        public ITaskItem[] References
        { get; set; } 
 
        public string RootNamespace
        { get; set; } 

        [Fx.Tag.KnownXamlExternal]
        public ITaskItem[] SourceCodeFiles
        { get; set; } 

        [Output] 
        public bool RequiresCompilationPass2 
        { get; set; }
 
        public string BuildTaskPath
        { get; set; }

        public bool IsInProcessXamlMarkupCompile 
        { get; set; }
 
        private static AppDomain inProcessAppDomain; 
        private static Dictionary referencesTimeStampCache;
        private Object referencesCacheLock = new Object(); 

        public override bool Execute()
        {
            if (IsInProcessXamlMarkupCompile) 
            {
                bool acquiredLock = false; 
                try 
                {
                    Monitor.TryEnter(referencesCacheLock, ref acquiredLock); 
                    if (acquiredLock)
                    {
                        return ReuseAppDomainAndExecute();
                    } 
                    else
                    { 
                        return GetAppDomainAndExecute(); 
                    }
                } 
                finally
                {
                    if (acquiredLock)
                    { 
                        Monitor.Exit(referencesCacheLock);
                    } 
                } 
            }
            else 
            {
                return GetAppDomainAndExecute();
            }
        } 

        bool ReuseAppDomainAndExecute() 
        { 
            AppDomain appDomain = null;
            bool createdNewAppDomain = false; 
            try
            {
                appDomain = GetInProcessAppDomain(out createdNewAppDomain);
                bool ret = ExecuteInternal(appDomain); 
                return ret;
            } 
            catch (Exception e) 
            {
                if (Fx.IsFatal(e)) 
                {
                    throw;
                }
                if (createdNewAppDomain) 
                {
                    XamlBuildTaskServices.LogException(this, e.Message); 
                    return false; 
                }
                else 
                {
                    AppDomain.Unload(inProcessAppDomain);
                    inProcessAppDomain = null;
                    return GetAppDomainAndExecute(); 
                }
            } 
        } 

        bool GetAppDomainAndExecute() 
        {
            AppDomain appDomain = null;
            try
            { 
                appDomain = CreateNewAppDomain();
                bool ret = ExecuteInternal(appDomain); 
                return ret; 
            }
            catch (Exception e) 
            {
                if (Fx.IsFatal(e))
                {
                    throw; 
                }
 
                XamlBuildTaskServices.LogException(this, e.Message); 
                return false;
            } 
            finally
            {
                if (appDomain != null)
                { 
                    AppDomain.Unload(appDomain);
                } 
            } 
        }
 
        bool ExecuteInternal(AppDomain appDomain)
        {
            PartialClassGenerationTaskInternal wrapper = (PartialClassGenerationTaskInternal)appDomain.CreateInstanceAndUnwrap(
                                                        Assembly.GetExecutingAssembly().FullName, 
                                                        typeof(PartialClassGenerationTaskInternal).FullName);
 
            PopulateBuildArtifacts(wrapper); 

            bool ret = wrapper.Execute(); 

            if (ret)
            {
                ExtractBuiltArtifacts(wrapper); 
            }
            else 
            { 
                IList logData = wrapper.LogData;
                foreach (LogData log in logData) 
                {
                    XamlBuildTaskServices.LogException(
                        this,
                        log.Message, 
                        log.FileName,
                        log.LineNumber, 
                        log.LinePosition); 
                }
            } 
            return ret;
        }

        AppDomain CreateNewAppDomain() 
        {
            return XamlBuildTaskServices.CreateAppDomain("PartialClassAppDomain_" + Guid.NewGuid(), BuildTaskPath); 
        } 

        // For Intellisense builds, we re-use the AppDomain for successive builds instead of creating a new one every time, 
        // if the references have not changed (there are no new references and they have not been updated since the last build)
        // This method accesses the static referencesTimeStampCache (indirectly).
        // To ensure thread safety, this method should be called inside a lock/monitor
        AppDomain GetInProcessAppDomain(out bool newAppDomain) 
        {
            newAppDomain = false; 
            if (inProcessAppDomain == null) 
            {
                inProcessAppDomain = CreateNewAppDomain(); 
                newAppDomain = true;
                UpdateReferenceCache();
            }
            else if (AreReferencesChanged()) 
            {
                AppDomain.Unload(inProcessAppDomain); 
                inProcessAppDomain = CreateNewAppDomain(); 
                newAppDomain = true;
                UpdateReferenceCache(); 
            }
            return inProcessAppDomain;
        }
 
        // This method accesses the static referencesTimeStampCache.
        // To ensure thread safety, this method should be called inside a lock/monitor 
        bool AreReferencesChanged() 
        {
            bool refsChanged = false; 
            if (referencesTimeStampCache == null || referencesTimeStampCache.Count != References.Length)
            {
                refsChanged = true;
            } 
            else
            { 
                foreach (var reference in References) 
                {
                    string fullPath = Path.GetFullPath(reference.ItemSpec); 
                    DateTime timeStamp = File.GetLastWriteTimeUtc(fullPath);
                    if (!referencesTimeStampCache.ContainsKey(fullPath)
                        || timeStamp > referencesTimeStampCache[fullPath]
                        || timeStamp == DateTime.MinValue) 
                    {
                        refsChanged = true; 
                        break; 
                    }
                } 
            }
            return refsChanged;
        }
 
        // This method accesses the static referencesTimeStampCache.
        // To ensure thread safety, this method should be called inside a lock/monitor 
        void UpdateReferenceCache() 
        {
            referencesTimeStampCache = new Dictionary(); 
            foreach (var reference in References)
            {
                string fullPath = Path.GetFullPath(reference.ItemSpec);
                DateTime timeStamp = File.GetLastWriteTimeUtc(fullPath); 
                referencesTimeStampCache.Add(fullPath, timeStamp);
            } 
        } 

        void PopulateBuildArtifacts(PartialClassGenerationTaskInternal wrapper) 
        {
            IList applicationMarkup = null;
            if (this.ApplicationMarkup != null)
            { 
                applicationMarkup = new List(this.ApplicationMarkup.Length);
                foreach (ITaskItem taskItem in this.ApplicationMarkup) 
                { 
                    applicationMarkup.Add(taskItem.ItemSpec);
                } 
            }
            wrapper.ApplicationMarkup = applicationMarkup;

            IList references = null; 
            if (this.References != null)
            { 
                references = new List(this.References.Length); 
                foreach (ITaskItem reference in this.References)
                { 
                    references.Add(reference.ItemSpec);
                }
            }
            wrapper.References = references; 

            IList sourceCodeFiles = null; 
            if (this.SourceCodeFiles != null) 
            {
                sourceCodeFiles = new List(this.SourceCodeFiles.Length); 
                foreach (ITaskItem taskItem in this.SourceCodeFiles)
                {
                    sourceCodeFiles.Add(taskItem.ItemSpec);
                } 
            }
            wrapper.SourceCodeFiles = sourceCodeFiles; 
 
            wrapper.Language = this.Language;
            wrapper.AssemblyName = this.AssemblyName; 
            wrapper.OutputPath = this.OutputPath;
            wrapper.RootNamespace = this.RootNamespace;
            wrapper.GeneratedSourceExtension = this.GeneratedSourceExtension;
            wrapper.IsInProcessXamlMarkupCompile = this.IsInProcessXamlMarkupCompile; 
        }
 
        void ExtractBuiltArtifacts(PartialClassGenerationTaskInternal wrapper) 
        {
            foreach (string resource in wrapper.GeneratedResources) 
            {
                this.generatedResources.Add(new TaskItem(resource));
            }
 
            foreach (string code in wrapper.GeneratedCodeFiles)
            { 
                this.generatedCodeFiles.Add(new TaskItem(code)); 
            }
 
            this.RequiresCompilationPass2 = wrapper.RequiresCompilationPass2;
        }
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK