Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / System.Activities / Microsoft / VisualBasic / Activities / XamlIntegration / VisualBasicExpressionConverter.cs / 1305376 / VisualBasicExpressionConverter.cs
//------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace Microsoft.VisualBasic.Activities.XamlIntegration
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Reflection;
using System.Xml.Linq;
using System.ComponentModel;
using System.Xaml;
using System.Windows.Markup;
static class VisualBasicExpressionConverter
{
static readonly Regex assemblyQualifiedNamespaceRegex = new Regex(
"clr-namespace:(?[^;]*);assembly=(?.*)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static VisualBasicSettings CollectXmlNamespacesAndAssemblies(ITypeDescriptorContext context)
{
// access XamlSchemaContext.ReferenceAssemblies
// for the Compiled Xaml scenario
IList xsCtxReferenceAssemblies = null;
IXamlSchemaContextProvider xamlSchemaContextProvider = context.GetService(typeof(IXamlSchemaContextProvider)) as IXamlSchemaContextProvider;
if (xamlSchemaContextProvider != null && xamlSchemaContextProvider.SchemaContext != null)
{
xsCtxReferenceAssemblies = xamlSchemaContextProvider.SchemaContext.ReferenceAssemblies;
if (xsCtxReferenceAssemblies != null && xsCtxReferenceAssemblies.Count == 0)
{
xsCtxReferenceAssemblies = null;
}
}
VisualBasicSettings settings = null;
IXamlNamespaceResolver namespaceResolver = (IXamlNamespaceResolver)context.GetService(typeof(IXamlNamespaceResolver));
if (namespaceResolver == null)
{
return null;
}
lock (AssemblyCache.XmlnsMappings)
{
// Fetch XmlnsMappings for the prefixes returned by the namespaceResolver service
foreach (NamespaceDeclaration prefix in namespaceResolver.GetNamespacePrefixes())
{
XNamespace xmlns = XNamespace.Get(prefix.Namespace);
XmlnsMapping mapping;
if (!AssemblyCache.XmlnsMappings.TryGetValue(xmlns, out mapping))
{
// Match a namespace of the form "clr-namespace:;assembly="
Match match = assemblyQualifiedNamespaceRegex.Match(prefix.Namespace);
if (match.Success)
{
mapping.ImportReferences = new HashSet();
mapping.ImportReferences.Add(
new VisualBasicImportReference
{
Assembly = match.Groups["assembly"].Value,
Import = match.Groups["namespace"].Value,
Xmlns = xmlns
});
}
else
{
mapping.ImportReferences = new HashSet();
}
AssemblyCache.XmlnsMappings[xmlns] = mapping;
}
if (!mapping.IsEmpty)
{
if (settings == null)
{
settings = new VisualBasicSettings();
}
foreach (VisualBasicImportReference importReference in mapping.ImportReferences)
{
if (xsCtxReferenceAssemblies != null)
{
// this is "compiled Xaml"
VisualBasicImportReference newImportReference;
AssemblyName currentAssemblyName = importReference.AssemblyName;
if (importReference.EarlyBoundAssembly != null)
{
if (xsCtxReferenceAssemblies.Contains(importReference.EarlyBoundAssembly))
{
newImportReference = importReference.Clone();
newImportReference.EarlyBoundAssembly = importReference.EarlyBoundAssembly;
settings.ImportReferences.Add(newImportReference);
}
continue;
}
for (int i = 0; i < xsCtxReferenceAssemblies.Count; i++)
{
AssemblyName xsCtxAssemblyName = VisualBasicHelper.GetFastAssemblyName(xsCtxReferenceAssemblies[i]);
if (AssemblySatisfiesReference(xsCtxAssemblyName, currentAssemblyName))
{
// bind this assembly early to the importReference
// so later AssemblyName resolution can be skipped
newImportReference = importReference.Clone();
newImportReference.EarlyBoundAssembly = xsCtxReferenceAssemblies[i];
settings.ImportReferences.Add(newImportReference);
break;
}
}
}
else
{
// this is "loose Xaml"
VisualBasicImportReference newImportReference = importReference.Clone();
if (importReference.EarlyBoundAssembly != null)
{
// VBImportReference.Clone() method deliberately doesn't copy
// its EarlyBoundAssembly to the cloned instance.
// we need to explicitly copy the original's EarlyBoundAssembly
newImportReference.EarlyBoundAssembly = importReference.EarlyBoundAssembly;
}
settings.ImportReferences.Add(newImportReference);
}
}
}
}
}
return settings;
}
// this code is borrowed from XamlSchemaContext
private static bool AssemblySatisfiesReference(AssemblyName assemblyName, AssemblyName reference)
{
if (reference.Name != assemblyName.Name)
{
return false;
}
if (reference.Version != null && !reference.Version.Equals(assemblyName.Version))
{
return false;
}
if (reference.CultureInfo != null && !reference.CultureInfo.Equals(assemblyName.CultureInfo))
{
return false;
}
byte[] requiredToken = reference.GetPublicKeyToken();
if (requiredToken != null)
{
byte[] actualToken = assemblyName.GetPublicKeyToken();
if (!AssemblyNameEqualityComparer.IsSameKeyToken(requiredToken, actualToken))
{
return false;
}
}
return true;
}
///
/// Static class used to cache assembly metadata.
///
///
///
///
/// XmlnsMappings for static assemblies are not GC'd. In v4.0 we can assume that all static assemblies
/// containing XmlnsDefinition attributes are non-collectible. The CLR will provide no public mechanism
/// for unloading a static assembly or specifying that a static assembly is collectible. While there
/// may be some small number of assemblies identified by the CLR as collectible, none will contain
/// XmlnsDefinition attributes. Should the CLR provide a public mechanism for unloading a static assembly
/// or specifying that a static assembly is collectible, we should revisit this decision based on scenarios
/// that flow from these mechanisms.
///
///
/// XmlnsMappings for dynamic assemblies are not created. This is because the hosted Visual Basic compiler
/// does not support dynamic assembly references. Should support for dynamic assembly references be
/// added to the Visual Basic compiler, we should strip away Assembly.IsDynamic checks from this class and
/// update the code ensure that VisualBasicImportReference instances are removed in a timely manner.
///
///
///
static class AssemblyCache
{
static bool initialized = false;
static Dictionary xmlnsMappings = new Dictionary(new XNamespaceEqualityComparer());
public static Dictionary XmlnsMappings
{
get
{
EnsureInitialized();
return xmlnsMappings;
}
}
static void EnsureInitialized()
{
if (initialized)
{
return;
}
lock (xmlnsMappings)
{
if (AssemblyCache.initialized)
{
return;
}
AppDomain.CurrentDomain.AssemblyLoad += delegate(object sender, AssemblyLoadEventArgs args)
{
Assembly assembly = args.LoadedAssembly;
if (assembly.IsDefined(typeof(XmlnsDefinitionAttribute), false) && ! assembly.IsDynamic)
{
lock (xmlnsMappings)
{
CacheLoadedAssembly(assembly);
}
}
};
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
for (int i = 0; i < assemblies.Length; ++i)
{
Assembly assembly = assemblies[i];
if (assembly.IsDefined(typeof(XmlnsDefinitionAttribute), false) && ! assembly.IsDynamic)
{
CacheLoadedAssembly(assembly);
}
}
initialized = true;
}
}
static void CacheLoadedAssembly(Assembly assembly)
{
// this VBImportReference is only used as an entry to the xmlnsMappings cache
// and is never meant to be Xaml serialized.
// those VBImportReferences that are to be Xaml serialized are created by Clone() method.
XmlnsDefinitionAttribute[] attributes = (XmlnsDefinitionAttribute[])assembly.GetCustomAttributes(typeof(XmlnsDefinitionAttribute), false);
string assemblyName = assembly.FullName;
XmlnsMapping mapping;
for (int i = 0; i < attributes.Length; ++i)
{
XNamespace xmlns = XNamespace.Get(attributes[i].XmlNamespace);
if (!xmlnsMappings.TryGetValue(xmlns, out mapping))
{
mapping.ImportReferences = new HashSet();
xmlnsMappings[xmlns] = mapping;
}
VisualBasicImportReference newImportReference = new VisualBasicImportReference
{
Assembly = assemblyName,
Import = attributes[i].ClrNamespace,
Xmlns = xmlns,
};
// early binding the assembly
// this leads to the short-cut, skipping the normal assembly resolution routine
newImportReference.EarlyBoundAssembly = assembly;
mapping.ImportReferences.Add(newImportReference);
}
}
class XNamespaceEqualityComparer : IEqualityComparer
{
public XNamespaceEqualityComparer()
{ }
bool IEqualityComparer.Equals(XNamespace x, XNamespace y)
{
return x == y;
}
int IEqualityComparer.GetHashCode(XNamespace x)
{
return x.GetHashCode();
}
}
}
///
/// Struct used to cache XML Namespace mappings.
///
struct XmlnsMapping
{
public HashSet ImportReferences;
public bool IsEmpty
{
get
{
return this.ImportReferences == null || this.ImportReferences.Count == 0;
}
}
}
}
}
// 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
- BindUriHelper.cs
- Emitter.cs
- Line.cs
- CorrelationService.cs
- DataGridViewCellEventArgs.cs
- Cloud.cs
- EncryptedReference.cs
- WebPartHeaderCloseVerb.cs
- XmlSchemaDocumentation.cs
- UnsafeMethods.cs
- ScrollItemPattern.cs
- RegistryPermission.cs
- Quaternion.cs
- ISAPIApplicationHost.cs
- SharedPerformanceCounter.cs
- UnsafeNativeMethods.cs
- EntitySqlQueryState.cs
- EntityTypeEmitter.cs
- SimpleWebHandlerParser.cs
- XNodeNavigator.cs
- DateTimeStorage.cs
- WinEventHandler.cs
- RequestCachePolicyConverter.cs
- XmlObjectSerializerWriteContextComplex.cs
- RequestStatusBarUpdateEventArgs.cs
- MailDefinition.cs
- LinkConverter.cs
- WebPartDisplayModeEventArgs.cs
- WebServiceParameterData.cs
- OracleRowUpdatingEventArgs.cs
- SqlUDTStorage.cs
- ExtenderProviderService.cs
- Scalars.cs
- GestureRecognitionResult.cs
- Privilege.cs
- FieldDescriptor.cs
- DataError.cs
- XmlSchemaAttributeGroupRef.cs
- UnmanagedMemoryStreamWrapper.cs
- PropertyItemInternal.cs
- ContextMarshalException.cs
- SQLStringStorage.cs
- X509ChainElement.cs
- XmlReflectionMember.cs
- TextTreeDeleteContentUndoUnit.cs
- XmlCountingReader.cs
- NameSpaceExtractor.cs
- BuildResult.cs
- ColumnTypeConverter.cs
- WebBrowserNavigatedEventHandler.cs
- ApplicationManager.cs
- KnownAssemblyEntry.cs
- XmlSchemaObjectTable.cs
- WindowsGraphicsWrapper.cs
- Version.cs
- TemplatePropertyEntry.cs
- FontSourceCollection.cs
- CheckBox.cs
- NameTable.cs
- XmlSerializerVersionAttribute.cs
- AppDomainProtocolHandler.cs
- SettingsContext.cs
- Version.cs
- WasHostedComPlusFactory.cs
- BehaviorEditorPart.cs
- CapabilitiesAssignment.cs
- SqlReorderer.cs
- XamlStyleSerializer.cs
- MouseActionConverter.cs
- MSAAWinEventWrap.cs
- ClientSettingsStore.cs
- InputEventArgs.cs
- DiagnosticStrings.cs
- isolationinterop.cs
- HostingEnvironment.cs
- DynamicDataResources.Designer.cs
- GregorianCalendarHelper.cs
- Automation.cs
- TypeUtil.cs
- DesignerActionUIService.cs
- HttpCapabilitiesBase.cs
- MaterialGroup.cs
- DiscoveryReferences.cs
- HierarchicalDataSourceControl.cs
- ResourceReader.cs
- StylusPlugin.cs
- XmlSchemaSimpleContentRestriction.cs
- basecomparevalidator.cs
- CompositeFontInfo.cs
- CodeTypeDeclarationCollection.cs
- ConnectionsZone.cs
- Panel.cs
- DataGridTextBoxColumn.cs
- TcpSocketManager.cs
- CurrencyManager.cs
- DSASignatureFormatter.cs
- WindowsImpersonationContext.cs
- SqlConnection.cs
- GradientStop.cs
- UniqueConstraint.cs