jaredpar / basic-reference-assemblies

Produce NuPkg files that have .NET Reference assemblies as resources
MIT License
96 stars 15 forks source link

Load resources lazily #33

Closed benjamin-hodgson closed 1 year ago

benjamin-hodgson commented 1 year ago

Today, the various properties on References are declared as get-only properties with an initialiser. Example:

public static PortableExecutableReference Accessibility { get; } = AssemblyMetadata.CreateFromImage(Resources.Accessibility).GetReference(filePath: "Accessibility.dll", display: "Accessibility (net472)");

There's also a static All property which stores all of the other PortableExecutableReferences in an array.

All of these initialisers always run (when the References class is first accessed), so all of the embedded resources are always loaded, even if you only need to use one of them. It looks like the resources total around 50MB (which is retained until the process terminates, since they are static fields), but also on the Desktop Framework there's additional garbage generated by the stream.CopyTo call in GetResourceBlob.

Would you be open to loading the resources lazily so that we only pay for what we use?

private static PortableExecutableReference? _accessibility;
public static PortableExecutableReference Accessibility
{
    get
    {
        if (_accessibility == null)
        {
            _accessibility = AssemblyMetadata.CreateFromImage(Resources.Accessibility).GetReference(filePath: "Accessibility.dll", display: "Accessibility (net472)");
        }
        return _accessibility;
    }
}

This could be changed to use System.Lazy if you want to be certain to load the resource once only (thread safety). Would you accept a pull request containing a change like this?

benjamin-hodgson commented 1 year ago

I should add that the properties in the Resources class do already load the resources lazily, but they're all evaluated in References's static constructor. So it's work-around-able (use the Resources directly and call CreateFromImage manually), but would be good to fix in the library if possible.