Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ResourceMap not found error when referencing a resource file within a portable class library

The problem I am facing has as follows:

I have developed a portable class library to encapsulate a service connection. Inside this class library there is a Resources.resw file containing strings. These strings are called only by methods of the class library (for example to override ToString() methods).

As I said this is a portable class library. If I reference it as a dll, or even as a project inside another solution, it gets built and compiles correctly. Then I make a call using a method of this library within my application, say

        ClientFacadeConnector connector = new ClientFacadeConnector();
        ICollection<SearchResult> results = null;
        string message = string.Empty;

        if (maxResults != -1) //Search with max Results
        {
            try
            {
                if (!contextQuery.Trim().Equals(string.Empty))
                {

                    results = await connector.GetConnected().SearchAsync(contextQuery, query, maxResults);
                    message = "Search with ContextQuery " + contextQuery + ", Query " + query + ", max results " + maxResults.ToString();
                }
                else
                {

                    results = await connector.GetConnected().SearchAsync(query, maxResults, true);
                    message = "...using normal Query search, Query " + query + ", max results " + maxResults.ToString();
                }
            }
            catch (IQserException ex)
            {
                message = ex.Message;
            }
        }


        if (results != null)
        {
            ICollection<LocalSearchResult> contentResults = new List<LocalSearchResult>();
            foreach (SearchResult s in results)
            {
                var q = s.ToString();
                var contentItem = await connector.GetConnected().GetContentAsync(s.ContentId);
                LocalSearchResult lContent = new LocalSearchResult(contentItem);
                lContent.Score = s.Score;
                lContent.Relevance = s.Relevance;
                lContent.MarkFullText(query);
                contentResults.Add(lContent);
            }

At the point where I call s.ToString() method, I get an error "Resource Map not found".

To explain where this comes from:

public static class AppResources
{
    private static ResourceLoader resourceLoader;

    static AppResources()
    {
        // Load local file Resources.resw by default
        resourceLoader = new ResourceLoader();            
    }

    public static string GetResources(string key)
    {
        if (string.IsNullOrEmpty(key))
            throw new ArgumentNullException("key");

        return resourceLoader.GetString(key);
    }

}

and inside the overridden ToString() method there is code that looks as follows:

    public override string ToString()
    {
        StringBuilder buf = new StringBuilder(AppResources.GetResources("InstrSearchResultContent"));

        if (ContentId != -1)
        {
            buf.Append(AppResources.GetResources("StringContent") + " ID:" + ContentId.ToString() + " | ");
        }
        else
        {
            buf.Append(AppResources.GetResources("StringNo") + AppResources.GetResources("StringContent") + "ID" + " | ");
        }
        ...

The resource file is called resources.resw and is the default resw file that ResourceLoader calls if no other is called.

Strangely enough, if I copy the resource file inside the client application locally, it is referenced correctly by all calls to the class library resource file and everything works.

This class library is supposed to be an SDK when finished. Do I need to distribute the resource file separately?

Such a problem I have never experienced with normal Class libraries and resx files. Resw is giving me the creeps..

like image 761
Achilles P. Avatar asked May 29 '12 14:05

Achilles P.


2 Answers

It looks like you have to specify the name of the resource map when you create the ResourceLoader, like this:

resourceLoader = new ResourceLoader("Assembly/ResourceFile");

For example, if your class library was called "Company.Lib.dll", and your resource file was "Resources.resw", you would use:

resourceLoader = new ResourceLoader("Company.Lib/Resources");

This doesn't seem to be documented fully on MSDN - it suggests that you can just specify the name of your resource file, but it might be that that only works for resource files that are in the Windows Store application project. It was this page that showed me that, for libraries, you need to specify the assembly name as well.

like image 92
Rory MacLeod Avatar answered Sep 21 '22 06:09

Rory MacLeod


I faced a similar issue when developing a UWP app with a class library. So I have a /Strings/en-Us/Resource.resw file in my library.

ResourceLoader.GetForCurrentView().GetString("someKey");

gives an exception

 new ResourceLoader("Company.Lib/Resources").GetString("someKey");

gives me a deprecation warning but works.

My solution which does not give a warning is this:

ResourceLoader.GetForViewIndependentUse("AssemblyNamespace/Resources").GetString("someKey");
like image 25
jannikb Avatar answered Sep 18 '22 06:09

jannikb