lkosson / reportviewercore

Recompilation of Microsoft.ReportViewer for .NET Core 3.1+
427 stars 123 forks source link

Automatic loading of RDLC code modules referenced assemblies #181

Closed UriHendler closed 1 month ago

UriHendler commented 7 months ago

Hi,

I want to automatically load assemblies referenced by a code module in the RDLC to match the behavior of .NET Framework. When running under .NET Framework, the runtime loads referenced assemblies automatically if they are found in the standard probing paths e.g. the directory of the currently executing program.

The AssemblyLocationResolver just calls Assembly.Load, which doesn't load referenced assemblies under .NET Core.

public string LoadAssemblyAndResolveLocation(string name)
{
    return Assembly.Load(name).Location;
}

Is there any way to do this without changing the code of the AssemblyLocationResolver?

Use Case

RDLC CodeModules section

<CodeModules>
  <CodeModule>ReportingCustomCode, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</CodeModule>
</CodeModules>

ReportingCustomCode assembly's references

image

When running under .NET Framework, as long as ReportingCustomCode.dll and NodaTime.dll are present in the directory of the current executing .exe, the runtime will load them automatically when calling Assembly.Load. (netstandard is loaded from the GAC.)

lkosson commented 7 months ago

Assembly name resolution and loading should work the same in this regard both in .NET Framework and .NET Core.

Don't quote me on that, but almost certainly .NET Framework didn't automatically load transitive dependencies when loading (by Assembly.Load or otherwise) an assembly. As far as I can tell, dependencies are located and loaded when a first method referencing those assemblies is JITted.

Only significant difference is when using AoT compilation / single .exe deployment - but then those .dlls simply don't exist in current directory.

If, for any reason, you need to load transitive dependencies of your assembly when it is loaded, simplest way to do it might be using module initializer which calls or otherwise explicitly references those assemblies.