Exemple #1
0
        /// <summary>
        /// Aggressively searches to find a resource based on a <see cref="Type"/> and resource name.
        /// <para/>
        /// The search attempts to find the resource starting at the location of the current
        /// class and attempts every combination of starting namespace and or starting assembly name
        /// (split on <c>.</c>) concatenated with the <paramref name="name"/>. For example, if the
        /// type passed is in the namespace <c>Foo.Bar</c> in an assembly named <c>Faz.Baz</c>
        /// and the name passed is <c>res.txt</c>, the following locations are searched in this order:
        /// <code>
        /// 1. res.txt
        /// 2. Faz.Baz.Foo.Bar.res.txt
        /// 3. Foo.Bar.res.txt
        /// 4. Faz.Baz.res.txt
        /// </code>
        /// <para/>
        /// Usage Note: This method effectively treats embedded resources as being in the same
        /// "class path" as the type that is passed, making it similar to the Class.getResource()
        /// method in Java.
        /// </summary>
        /// <param name="assembly">This assembly.</param>
        /// <param name="type">A type in the same namespace as the resource.</param>
        /// <param name="name">The resource name to locate.</param>
        /// <returns>The resource, if found; if not found, returns <c>null</c>.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="assembly"/>, <paramref name="type"/> or <paramref name="name"/> is <c>null</c>.</exception>
        public static string FindResource(this Assembly assembly, Type type, string name)
        {
            if (assembly == null)
            {
                throw new ArgumentNullException(nameof(assembly));
            }
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            TypeAndResource key = new TypeAndResource(type, name);

            return(resourceCache.GetOrAdd(key, (key) =>
            {
                string[] resourceNames = assembly.GetManifestResourceNames();
                string resourceName = resourceNames.Where(x => x.Equals(name, StringComparison.Ordinal)).FirstOrDefault();

                // If resourceName is not null, we have an exact match, don't search
                if (resourceName == null)
                {
#if FEATURE_TYPEEXTENSIONS_GETTYPEINFO
                    string assemblyName = type.GetTypeInfo().Assembly.GetName().Name;
                    string namespaceName = type.GetTypeInfo().Namespace;
#else
                    string assemblyName = type.Assembly.GetName().Name;
                    string namespaceName = type.Namespace;
#endif

                    // Search by assembly + namespace
                    string resourceToFind = string.Concat(namespaceName, ".", name);
                    if (!TryFindResource(resourceNames, assemblyName, resourceToFind, name, out resourceName))
                    {
                        string found1 = resourceName;

                        // Search by namespace only
                        if (!TryFindResource(resourceNames, null, resourceToFind, name, out resourceName))
                        {
                            string found2 = resourceName;

                            // Search by assembly name only
                            resourceToFind = string.Concat(assemblyName, ".", name);
                            if (!TryFindResource(resourceNames, null, resourceToFind, name, out resourceName))
                            {
                                // Take the first match of multiple, if there are any
                                resourceName = found1 ?? found2 ?? resourceName;
                            }
                        }
                    }
                }
                return resourceName;
            }));
        }
Exemple #2
0
        /// <summary>
        /// Aggressively searches to find a resource based on a resource name.
        /// Attempts to find the resource file by prepending the assembly name
        /// with the resource name and then removing the segements of the
        /// name from left to right until a match is found.
        /// <para/>
        /// The search attempts to find the resource starting at the location of the current
        /// class and attempts every combination of starting namespace and or starting assembly name
        /// (split on <c>.</c>) concatenated with the <paramref name="name"/>. For example, if the
        /// type passed is in the namespace <c>Foo.Bar</c> in an assembly named <c>Faz.Baz</c>
        /// and the name passed is <c>res.txt</c>, the following locations are searched in this order:
        /// <code>
        /// 1. res.txt
        /// 2. Faz.Baz.Foo.Bar.res.txt
        /// 3. Foo.Bar.res.txt
        /// 4. Faz.Baz.res.txt
        /// </code>
        /// <para/>
        /// Usage Note: This method effectively treats embedded resources as being in the same
        /// "class path" as the type that is passed, making it similar to the <c>Class.getResource()</c>
        /// method in Java.
        /// </summary>
        /// <param name="assembly">This assembly.</param>
        /// <param name="name">The resource name to locate.</param>
        /// <returns>The resource, if found; if not found, returns <c>null</c>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="assembly"/> or <paramref name="name"/> is <c>null</c>.</exception>
        public static string FindResource(this Assembly assembly, string name)
        {
            if (assembly == null)
            {
                throw new ArgumentNullException(nameof(assembly));
            }
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            var key = new TypeAndResource(null, name);

            return(resourceCache.GetOrAdd(key, (key) =>
            {
                string[] resourceNames = assembly.GetManifestResourceNames();
                string resourceName = resourceNames.Where(x => x.Equals(name)).FirstOrDefault();

                // If resourceName is not null, we have an exact match, don't search
                if (resourceName == null)
                {
                    string assemblyName = assembly.GetName().Name;
                    int lastDot = assemblyName.LastIndexOf('.');
                    do
                    {
                        // Search by assembly name only
                        string resourceToFind = string.Concat(assemblyName, ".", name);
                        TryFindResource(resourceNames, null, resourceToFind, name, out resourceName);

                        // Continue searching by removing sections after the . from the assembly name
                        // until we have a match.
                        lastDot = assemblyName.LastIndexOf('.');
                        assemblyName = lastDot >= 0 ? assemblyName.Substring(0, lastDot) : null;
                    } while (assemblyName != null && resourceName == null);

                    if (resourceName == null)
                    {
                        // Try again without using the assembly name
                        TryFindResource(resourceNames, null, name, name, out resourceName);
                    }
                }

                return resourceName;
            }));
        }
Exemple #3
0
        /// <summary>
        /// Aggressively searches to find a resource based on a <see cref="Type"/> and resource name.
        /// </summary>
        /// <param name="assembly">this assembly</param>
        /// <param name="type">a type in the same namespace as the resource</param>
        /// <param name="name">the resource name to locate</param>
        /// <returns>the resource, if found; if not found, returns <c>null</c></returns>
        public static string FindResource(this Assembly assembly, Type type, string name)
        {
            name = ConvertResourceName(name);
            string          resourceName;
            TypeAndResource key = new TypeAndResource(type, name);

            if (!resourceCache.TryGetValue(key, out resourceName))
            {
                string[] resourceNames = assembly.GetManifestResourceNames();
                resourceName = resourceNames.Where(x => x.Equals(name)).FirstOrDefault();

                // If resourceName is not null, we have an exact match, don't search
                if (resourceName == null)
                {
                    string assemblyName  = type.GetTypeInfo().Assembly.GetName().Name;
                    string namespaceName = type.GetTypeInfo().Namespace;

                    // Search by assembly + namespace
                    string resourceToFind = string.Concat(namespaceName, ".", name);
                    if (!TryFindResource(resourceNames, assemblyName, resourceToFind, name, out resourceName))
                    {
                        string found1 = resourceName;

                        // Search by namespace only
                        if (!TryFindResource(resourceNames, null, resourceToFind, name, out resourceName))
                        {
                            string found2 = resourceName;

                            // Search by assembly name only
                            resourceToFind = string.Concat(assemblyName, ".", name);
                            if (!TryFindResource(resourceNames, null, resourceToFind, name, out resourceName))
                            {
                                // Take the first match of multiple, if there are any
                                resourceName = found1 ?? found2 ?? resourceName;
                            }
                        }
                    }
                }

                resourceCache[key] = resourceName;
            }

            return(resourceName);
        }