Code:
/ 4.0 / 4.0 / 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.
//------------------------------------------------------------
// 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

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Keywords.cs
- ObjectStateEntry.cs
- EntityParameterCollection.cs
- AutomationElementIdentifiers.cs
- ImageDrawing.cs
- Viewport3DAutomationPeer.cs
- ComponentDispatcherThread.cs
- DeleteMemberBinder.cs
- ContentPropertyAttribute.cs
- TextPenaltyModule.cs
- CharStorage.cs
- WindowsGraphicsWrapper.cs
- RegexWriter.cs
- MatrixUtil.cs
- UriScheme.cs
- Track.cs
- TextTreeInsertElementUndoUnit.cs
- AccessViolationException.cs
- DynamicValidatorEventArgs.cs
- EventLogQuery.cs
- NetTcpBindingCollectionElement.cs
- Pkcs7Signer.cs
- OleDbDataReader.cs
- CommandField.cs
- MorphHelpers.cs
- GeneralEndpointIdentity.cs
- TransformValueSerializer.cs
- EdmValidator.cs
- DataGridViewCellValidatingEventArgs.cs
- ShutDownListener.cs
- XmlCompatibilityReader.cs
- Compiler.cs
- GridViewEditEventArgs.cs
- MessageBox.cs
- NetCodeGroup.cs
- TextEncodedRawTextWriter.cs
- XsltException.cs
- Section.cs
- ListBindableAttribute.cs
- TextDecorationLocationValidation.cs
- DrawingAttributesDefaultValueFactory.cs
- FontWeight.cs
- WindowsFormsHostPropertyMap.cs
- DataGridViewSelectedCellsAccessibleObject.cs
- UniformGrid.cs
- XPathArrayIterator.cs
- ExponentialEase.cs
- WebHeaderCollection.cs
- InheritanceRules.cs
- SystemIcmpV6Statistics.cs
- FrugalMap.cs
- FreezableCollection.cs
- ParameterBinding.cs
- TypeDelegator.cs
- DelegateTypeInfo.cs
- CodeIndexerExpression.cs
- addressfiltermode.cs
- CroppedBitmap.cs
- CompressionTransform.cs
- RootBuilder.cs
- DbProviderFactory.cs
- Stylus.cs
- HostingPreferredMapPath.cs
- NumericExpr.cs
- SamlAuthenticationClaimResource.cs
- OleDbException.cs
- DataGridViewComboBoxEditingControl.cs
- DataGridCellsPanel.cs
- AutomationFocusChangedEventArgs.cs
- ApplicationGesture.cs
- ObjectDisposedException.cs
- TTSEngineTypes.cs
- ModelTreeEnumerator.cs
- IdentityManager.cs
- X509Chain.cs
- RtfToXamlLexer.cs
- XmlSerializerVersionAttribute.cs
- DeviceContext.cs
- QueueException.cs
- ByteStorage.cs
- FlowDocumentReader.cs
- DataGridPreparingCellForEditEventArgs.cs
- CircleHotSpot.cs
- XmlIterators.cs
- BooleanExpr.cs
- WhitespaceSignificantCollectionAttribute.cs
- SqlClientWrapperSmiStream.cs
- ScrollItemProviderWrapper.cs
- MetadataArtifactLoaderComposite.cs
- XpsLiterals.cs
- RegexCompilationInfo.cs
- EntityContainerEntitySet.cs
- SqlDataRecord.cs
- WCFBuildProvider.cs
- ReflectionUtil.cs
- LifetimeManager.cs
- SafeEventLogWriteHandle.cs
- FrugalMap.cs
- DictionarySectionHandler.cs
- DataFormat.cs