Search code examples
c#reflectionreflection.emitresourcemanagerassemblybuilder

Reflection | Emit | Dynamic Resource Generation - Added resource values using IResourceWriter.AddResource(key,value) cannot read


I am trying to generate an assembly file with some resources. I am using System.Reflection.Emit.ModuleBuilder to define resources. AssemblyBuilder save assembly without giving any errors but when I am trying read resources, ResourceManager doesn't have any entry in it's ResourceSets. I am not sure AssemblyBuilder doesn't save added resources or my resource reading code has issues.

Assembly generation code:

public void GenerateAsm()
    {
        string myAsmName = "MyAssembly.resources";
        string myAsmFileName = myAsmName + ".dll";
        string resourceName = "MyAssembly.Resource.fr.resources";

        AppDomain appDomain = Thread.GetDomain();
        AssemblyName asmName = new AssemblyName();
        asmName.Name = myAsmName;
        AssemblyBuilder myAsmBuilder = appDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);

        ModuleBuilder myModuleBuilder = myAsmBuilder.DefineDynamicModule(myAsmFileName,myAsmFileName);
        IResourceWriter rw = myModuleBuilder.DefineResource(resourceName, "My Description", ResourceAttributes.Public);

        rw.AddResource("ResKey1", "Resource value 1.");
        rw.AddResource("ResKey2", "Resource value 2.");
        myAsmBuilder.Save(myAsmFileName);    
    }

Resource reading code:

public void ReadResource()
    {
        ResourceManager rm = new ResourceManager("MyAssembly.Resource.fr.resources", Assembly.LoadFrom("MyAssembly.resources.dll"));
        string greeting = rm.GetString("ResKey1");
    }

Resource manager can load resource but it doesn't have any key value pairs.


Solution

  • The generated assembly contains the resource values:

    enter image description here

    So the problem in a ResourceManager.

    The ResourceManager class retrieves resources from a binary .resources file that is embedded in an assembly or from a standalone .resources file

    And resources you are creating is not embeded binary .resources files

    Try ResourceReader, that fits better to your situation

    using (var reader = new ResourceReader(asm.GetManifestResourceStream(resourceName)))
    {
        foreach (DictionaryEntry entry in reader)
        {
    
        }
    }
    

    enter image description here