VisualBasicExpressionConverter.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 / 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

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