﻿# Assembly scanning

<!-- Version variant: core_9; default: [/nservicebus/hosting/assembly-scanning.md](/nservicebus/hosting/assembly-scanning.md) -->


NServiceBus scans assemblies at endpoint startup to automatically detect and load [message types](/nservicebus/messaging/messages-events-commands.md), [message handlers](/nservicebus/handlers/index.md), [features](/nservicebus/pipeline/features.md), and [installers](/nservicebus/operations/installers.md).

> [!NOTE]
> Assembly scanning is optional starting in NServiceBus version 10.2. For the modern explicit registration approaches, see [Registering Handlers and Sagas](/nservicebus/handlers-and-sagas-registration.md).

There are some cases where finer control over which assemblies are loaded is required:

* To limit the number of assemblies being scanned and hence improve startup time.
* If hosting multiple endpoints out of the same directory, each endpoint may require loading a subset of assemblies.

> [!NOTE]
> NServiceBus extensions such as `NServiceBus.RavenDB.dll` are not considered a core assembly but still must be included when customizing the assembly scanning.

## AppDomain assemblies

By default, the assemblies already loaded into the AppDomain are scanned. The endpoint can also be configured to disable AppDomain assembly scanning:

<!-- snippet: ScanningApDomainAssemblies -->

```cs
var scanner = endpointConfiguration.AssemblyScanner();
scanner.ScanAppDomainAssemblies = false;
```

<!-- endsnippet -->

## Assembly files

By default, all assemblies in the endpoint's `bin` directory are scanned for related interfaces so that the endpoint can configure them automatically.

### Additional assembly scanning path

> [!NOTE]
> This configuration option is available only in NServiceBus version 7.4 and above.

Assembly scanning can be configured to scan an additional path for assemblies outside the default scanning path.

<!-- snippet: AdditionalAssemblyScanningPath -->

```cs
var scanner = endpointConfiguration.AssemblyScanner();
scanner.AdditionalAssemblyScanningPath = additionalPathToScanAssemblies;
```

<!-- endsnippet -->

### Nested directories

Nested directories are **not** scanned for assemblies by default. Nested directory assembly scanning can be enabled using:

<!-- snippet: ScanningNestedAssebliesEnabled -->

```cs
var scanner = endpointConfiguration.AssemblyScanner();
scanner.ScanAssembliesInNestedDirectories = true;
```

<!-- endsnippet -->

### Disable assembly files scanning

Scanning of assemblies deployed to the `bin` folder (and other configured scanning locations) can be disabled:

<!-- snippet: disable-file-scanning -->

```cs
endpointConfiguration.AssemblyScanner().ScanFileSystemAssemblies = false;
```

<!-- endsnippet -->

> [!WARNING]
> When disabling scanning of assembly files, ensure that all required assemblies are correctly loaded into the AppDomain at endpoint startup and that AppDomain assembly scanning is enabled.

## Assemblies to scan

The assemblies being scanned can further be controlled via user-defined exclusions. This supports common scenarios removing specific assemblies from scanning without the risk of accidentally excluding required assemblies.

### Exclude specific assemblies by name

<!-- snippet: ScanningExcludeByName -->

```cs
var scanner = endpointConfiguration.AssemblyScanner();
scanner.ExcludeAssemblies("MyAssembly1.dll", "MyAssembly2.dll");
```

<!-- endsnippet -->

### Exclude assemblies by wildcard

Multiple assemblies can be excluded by wildcards using the following approach:

<!-- snippet: ScanningAssembliesWildcard -->

```cs
var scanner = endpointConfiguration.AssemblyScanner();

var excludeRegexs = new List<string>
{
    @"App_Web_.*\.dll",
    @".*\.resources\.dll"
};

var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
foreach (var fileName in Directory.EnumerateFiles(baseDirectory, "*.dll")
    .Select(Path.GetFileName))
{
    foreach (var pattern in excludeRegexs)
    {
        if (Regex.IsMatch(fileName, pattern, RegexOptions.IgnoreCase))
        {
            scanner.ExcludeAssemblies(fileName);
            break;
        }
    }
}
```

<!-- endsnippet -->

### Exclude specific types

<!-- snippet: ScanningExcludeTypes -->

```cs
var scanner = endpointConfiguration.AssemblyScanner();
scanner.ExcludeTypes(type1, type2);
```

<!-- endsnippet -->

## Suppress scanning exceptions

> [!NOTE]
> This configuration option is only available in NServiceBus 6.2 and above.

By default, exceptions that occurred during assembly scanning will be re-thrown. Those exceptions can be ignored using the following:

<!-- snippet: SwallowScanningExceptions -->

```cs
var scanner = endpointConfiguration.AssemblyScanner();
scanner.ThrowExceptions = false;
```

<!-- endsnippet -->

> [!WARNING]
> Ignoring assembly scanning exceptions can cause the endpoint not to load some features, behaviors, messages or message handlers and cause incorrect behavior.


