Пример #1
0
        /// <summary>
        /// Scans an assembly for exported namespaces, adding them to the
        /// mapping of valid namespaces. Note that for a given namespace
        /// a.b.c.d, each of a, a.b, a.b.c and a.b.c.d are considered to
        /// be valid namespaces (to better match Python import semantics).
        /// </summary>
        internal static void ScanAssembly(Assembly assembly)
        {
            if (assembly.GetCustomAttribute <PyExportAttribute>()?.Export == false)
            {
                return;
            }
            // A couple of things we want to do here: first, we want to
            // gather a list of all of the namespaces contributed to by
            // the assembly.
            foreach (Type t in GetTypes(assembly))
            {
                string ns = t.Namespace ?? "";
                if (!namespaces.ContainsKey(ns))
                {
                    string[] names = ns.Split('.');
                    var      s     = "";
                    for (var n = 0; n < names.Length; n++)
                    {
                        s = n == 0 ? names[0] : s + "." + names[n];
                        if (namespaces.TryAdd(s, new ConcurrentDictionary <Assembly, string>()))
                        {
                            ImportHook.AddNamespace(s);
                        }
                    }
                }

                if (ns != null)
                {
                    namespaces[ns].TryAdd(assembly, string.Empty);
                }

                if (ns != null && t.IsGenericTypeDefinition)
                {
                    GenericUtil.Register(t);
                }
            }
        }
Пример #2
0
        public static Assembly AddReference(string name)
        {
            AssemblyManager.UpdatePath();
            var      origNs   = AssemblyManager.GetNamespaces();
            Assembly assembly = null;

            assembly = AssemblyManager.FindLoadedAssembly(name);
            if (assembly == null)
            {
                assembly = AssemblyManager.LoadAssemblyPath(name);
            }
            if (assembly == null)
            {
                assembly = AssemblyManager.LoadAssembly(name);
            }
            if (assembly == null)
            {
                assembly = AssemblyManager.LoadAssemblyFullPath(name);
            }
            if (assembly == null)
            {
                throw new FileNotFoundException($"Unable to find assembly '{name}'.");
            }
            // Classes that are not in a namespace needs an extra nudge to be found.
            ImportHook.UpdateCLRModuleDict();

            // A bit heavyhanded, but we can't use the AssemblyManager's AssemblyLoadHandler
            // method because it may be called from other threads, leading to deadlocks
            // if it is called while Python code is executing.
            var currNs = AssemblyManager.GetNamespaces().Except(origNs);

            foreach (var ns in currNs)
            {
                ImportHook.AddNamespace(ns);
            }
            return(assembly);
        }