-
Notifications
You must be signed in to change notification settings - Fork 564
Description
Steps to Reproduce
Given code like the following:
// Some static dictionary somewhere:
public static Dictionary<string, Func<object>> Services { get; } = new Dictionary<string, Func<object>>();
// From MainActivity.cs;
Services.Add(nameof(BarServices.Bar), CreateBar);
Services.Add(nameof(FooServices.Foo), CreateFoo);And given that the two methods are defined to explicitly not be inlined or otherwise loaded until invoked:
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
static object CreateBar() => new BarServices.Bar();
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
static object CreateFoo() => new FooServices.Foo();And given FooServices.dll and BarServices.dll are two completely independent assemblies from the main app's, it would be highly desirable for the assemblies to only be loaded when the dictionary entry is accessed and the delegate is invoked, instead of happening on app start, which slows down the process "unnecessarily".
The ~same code in a .NET app properly lazy loads the assemblies as needed:
public static Dictionary<string, Func<object>> Services { get; } = new Dictionary<string, Func<object>>(StringComparer.OrdinalIgnoreCase);
static void Main(string[] args)
{
// Both this approach as well as the inline lambda properly delay-load the assemblies
//Services.Add(nameof(BarServices.Bar), CreateBar);
//Services.Add(nameof(FooServices.Foo), CreateFoo);
Services.Add(nameof(BarServices.Bar), () => new BarServices.Bar());
Services.Add(nameof(FooServices.Foo), () => new FooServices.Foo());
var line = "";
while ((line = Console.ReadLine()).Length > 0)
{
Console.WriteLine(Services[line.Trim()].Invoke().ToString());
}
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
static object CreateBar() => new BarServices.Bar();
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
static object CreateFoo() => new FooServices.Foo();This is important for apps that use assembly-partitioning to split logic across modules, which should only be loaded whenever needed (i.e. when the UI that consumes them is navigated to, say).
Expected Behavior
Assemblies are lazy-loaded.
Actual Behavior
Both assemblies are loaded up-front:
03-19 15:36:33.243 nexus_5x Debug 13769 Mono Assembly FooServices[0x9de4ed60] added to domain RootDomain, ref_count=1
Version Information
Currently verified against 15.7 pre2