0

I recently followed an example for pre-loading several DLLs from the bin folder as described here: https://stackoverflow.com/a/5599581/1099519

This actually did work as expected, but I am using SonarLint for VisualStudio and in the following line of code is underlinded and marked as a "Code Smell":

Assembly.LoadFile(dll);

Stating the following S3885 (https://rules.sonarsource.com/csharp/RSPEC-3885):

The parameter to Assembly.Load includes the full specification of the dll to be loaded. Use another method, and you might end up with a dll other than the one you expected.

This rule raises an issue when Assembly.LoadFrom, Assembly.LoadFile, or Assembly.LoadWithPartialName is called.

So I gave it a try and changed it into Assembly.Load(dll); as recommended:

private const string BinFolderName = "bin";
public static void LoadAllBinDirectoryAssemblies(string fileMask)
{

    string binPath = System.AppDomain.CurrentDomain.BaseDirectory;

    if(Directory.Exists(Path.Combine(binPath, BinFolderName)))
    {
        binPath = Path.Combine(binPath, BinFolderName);
    }

    foreach (string dll in Directory.GetFiles(binPath, fileMask, SearchOption.AllDirectories))
    {
        try
        {
            Assembly.Load(dll); // Before: Assembly.LoadFile
        }
        catch (FileLoadException ex)
        {
            // The Assembly has already been loaded.
        }
        catch (BadImageFormatException)
        {
            // If a BadImageFormatException exception is thrown, the file is not an assembly.
        }

    }
}

But using the recommended method an FileLoadException is thrown:

Could not load file or assembly 'C:\SomePath\SomeDll.dll' or one of its dependencies. The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047)

The reason: The string of Assembly.Load is not a file path, it is actually a class name such as "SampleAssembly, Version=1.0.2004.0, Culture=neutral, PublicKeyToken=8744b20f8da049e3".

Is this simply a false-positive from SonarLint or does a "compliant" way exist?

DominikAmon
  • 892
  • 1
  • 14
  • 26
  • Did you reference it in your solution? – Hugo Woesthuis Oct 14 '18 at 19:24
  • Show the code please. I believe the code smell is accurate but it needs to be properly implemented. – Michael Puckett II Oct 14 '18 at 19:27
  • 1
    Please read the documentation for [Assembly.Load](https://learn.microsoft.com/en-gb/dotnet/api/system.reflection.assembly.load?view=netframework-4.7.2#System_Reflection_Assembly_Load_System_String_). The string argument is not supposed to be the path to an assembly DLL. –  Oct 14 '18 at 19:28
  • You should also check the NFusionLog (in vs developer prompt `Fuslogvw.exe`) what exactly can't be found – lukaszberwid Oct 14 '18 at 19:30
  • I added the full code example. In my example the other class libraries are actually referenced (but it actually should not be necessary.) – DominikAmon Oct 14 '18 at 19:38
  • @elgonzo : I updated this posting it according to the documentation. – DominikAmon Oct 14 '18 at 19:42
  • Assembly.LoadFile() is wrong 99.99% of the time. One of the worst-named .NET methods, it must only be used when loading an assembly more than once is required. Exceedingly rare, an app that displays assembly metadata and wants to compare versions would need that. Too bad they gave LoadFrom() the code-smell label as well, but that's what you want. – Hans Passant Oct 14 '18 at 21:42
  • If LoadFile is wrong for 99.99% of the time, then what would be the more accurate/safe approach of pre-loading all assemblies in the bin folder? My use-case is to scan all assemblies for classes that derive from one particual class. Those classes can be basically everywhere in the class libraries (even if the class library is not yet loaded). – DominikAmon Oct 15 '18 at 18:18

0 Answers0