diff --git a/src/NServiceBus.Core.Tests/AssemblyScanner/When_exclusion_predicate_is_used.cs b/src/NServiceBus.Core.Tests/AssemblyScanner/When_exclusion_predicate_is_used.cs index 3e9d939e081..7c7f2d6337c 100644 --- a/src/NServiceBus.Core.Tests/AssemblyScanner/When_exclusion_predicate_is_used.cs +++ b/src/NServiceBus.Core.Tests/AssemblyScanner/When_exclusion_predicate_is_used.cs @@ -29,5 +29,22 @@ public void No_files_explicitly_excluded_are_returned() Assert.That(explicitlySkippedDll, Is.Not.Null); Assert.That(explicitlySkippedDll.SkipReason, Contains.Substring("File was explicitly excluded from scanning")); } + + [Test] + public void Assemblies_that_have_no_extension_can_be_excluded() + { + var results = new AssemblyScanner(Path.Combine(TestContext.CurrentContext.TestDirectory, "TestDlls")) + { + AssembliesToSkip = new List { "some.random" }, + ScanAppDomainAssemblies = false + } + .GetScannableAssemblies(); + + var skippedFiles = results.SkippedFiles; + var explicitlySkippedDll = skippedFiles.FirstOrDefault(s => s.FilePath.Contains("some.random.dll")); + + Assert.That(explicitlySkippedDll, Is.Not.Null); + Assert.That(explicitlySkippedDll.SkipReason, Contains.Substring("File was explicitly excluded from scanning")); + } } } \ No newline at end of file diff --git a/src/NServiceBus.Core.Tests/TestDlls/some.random.dll b/src/NServiceBus.Core.Tests/TestDlls/some.random.dll new file mode 100644 index 00000000000..dadece6b799 --- /dev/null +++ b/src/NServiceBus.Core.Tests/TestDlls/some.random.dll @@ -0,0 +1 @@ +this is not a DLL \ No newline at end of file diff --git a/src/NServiceBus.Core/Hosting/Helpers/AssemblyScanner.cs b/src/NServiceBus.Core/Hosting/Helpers/AssemblyScanner.cs index 4e5f9722fdf..dac4d62ebbc 100644 --- a/src/NServiceBus.Core/Hosting/Helpers/AssemblyScanner.cs +++ b/src/NServiceBus.Core/Hosting/Helpers/AssemblyScanner.cs @@ -57,9 +57,14 @@ internal AssemblyScanner(Assembly assemblyToScan) internal IReadOnlyCollection AssembliesToSkip { - set => assembliesToSkip = new HashSet(value.Select(Path.GetFileNameWithoutExtension), StringComparer.OrdinalIgnoreCase); + set => assembliesToSkip = new HashSet(value.Select(RemoveExtension), StringComparer.OrdinalIgnoreCase); } + static string RemoveExtension(string assemblyName) => + assemblyName.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) || assemblyName.EndsWith(".exe", StringComparison.OrdinalIgnoreCase) + ? Path.GetFileNameWithoutExtension(assemblyName) + : assemblyName; + internal IReadOnlyCollection TypesToSkip { set => typesToSkip = new HashSet(value); @@ -349,9 +354,7 @@ static List ScanDirectoryForAssemblyFiles(string directoryToScan, bool return fileInfo; } - bool IsExcluded(string assemblyNameOrFileNameWithoutExtension) => - assembliesToSkip.Contains(assemblyNameOrFileNameWithoutExtension) || - DefaultAssemblyExclusions.Contains(assemblyNameOrFileNameWithoutExtension); + bool IsExcluded(string assemblyName) => assembliesToSkip.Contains(assemblyName) || DefaultAssemblyExclusions.Contains(assemblyName); // The parameter and return types of this method are deliberately using the most concrete types // to avoid unnecessary allocations