Automatic Module Discovery With Autofac — Simplified Registration

Automatic Module Discovery With Autofac — Simplified Registration

In the realm of software development, modularity stands as a cornerstone principle. It not only ensures that software components remain organized but also facilitates easier maintenance and scalability. One tool that has gained traction in the .NET ecosystem for its prowess in module management is Autofac. Serving as a dependency injection container, Autofac offers developers a structured way to instantiate, configure, and retrieve application components. But what about automatic module discovery?

In this article, we’ll look through why we might want automatic module discovery and how we can achieve this with Autofac! I’ll do my best to cover both the pros and the cons because it’s important that we remain pragmatic. While I love using Autofac and automatic module discovery like this for my plugin-based solutions, there are always tradeoffs!

Basics of Autofac and Module Management

As mentioned, Autofac is a popular Inversion of Control (IoC) container for .NET. At its core, it manages the creation and disposal of services or components. One of its standout features is its ability to manage components across various lifetimes, ensuring that resources are efficiently utilized and disposed of.

A significant aspect of Autofac is its module system. In Autofac, a module is a small, organized unit that encapsulates a set of related component registrations. This system allows developers to group related services together, making it easier to manage and configure them. By leveraging modules, developers can ensure that their applications remain organized, especially as they scale and evolve.

Subscribe to Dev Leader Weekly

The Need for Automatic Module Discovery

As applications grow and evolve, the number of modules and services they encompass can increase significantly. Manually registering each module can become a tedious and error-prone task. This manual approach can lead to oversights, where certain modules might be left unregistered, leading to runtime errors. Moreover, as the number of modules increases, the complexity of managing dependencies between them can become overwhelming.

Automating the module discovery process offers a solution to these challenges. By automatically discovering and registering modules, developers can ensure that all necessary components are correctly initialized without manual intervention. This not only reduces the potential for errors but also streamlines the development process, allowing developers to focus on building functionality rather than managing module registrations.

Scanning Directories for Assemblies

Setting Up the Environment

Before diving into the code, it’s essential to ensure the environment is correctly set up. For this demonstration, you’ll need:

  1. A .NET Core application.

  2. Autofac NuGet package installed in your project.

  3. A directory containing the assemblies you wish to scan.

This article assumes you have some prior basic knowledge of Autofac, but if not, you can check this article out to get started with Autofac!

Code Example: Directory Scanning

To scan a directory for assemblies, we can leverage the .NET Core’s built-in System.Reflection namespace. Let’s walk through this, step by step, so that we can see how to facilitate automatic module discovery with Autofac!

First, we’ll want to decide which directory or directories we want to look at, and then from there, consider which files we are interested in. This can look very different from project to project depending on what your needs are. Don’t marry yourself to this exact solution but listing the files could look like the following:

string pathToAssemblies = @"C:\path\to\your\assemblies";
var allFiles = Directory.GetFiles(pathToAssemblies, "*.dll");

You may want to consider other types of filters (i.e. not just *.dll), go the multi-folder route, or even switch away from using LINQ entirely if you prefer writing it out with loops. Once we have the files in question though, we’ll want to load the assemblies:

var assemblies = allFiles.Select(file => Assembly.LoadFrom(file)).ToArray();

Again, the code above can be changed from LINQ to using loops depending on your style. You could also consider safety mechanisms for loading assemblies and handling exceptions, but this will be situational for your application.

Finally, we’ll want to register these assemblies with our Autofac container builder:

var builder = new ContainerBuilder();
foreach (var assembly in assemblies)

Or without LINQ:

string pathToAssemblies = @"C:\path\to\your\assemblies";
var builder = new ContainerBuilder();

foreach (var file in Directory.GetFiles(pathToAssemblies, "*.dll"))
    var assembly = Assembly.LoadFrom(file);

With these steps, you’ve successfully scanned a directory for assemblies and registered the contained Autofac modules. This approach ensures that as you add new modules to the directory, they’ll be automatically discovered and registered without any additional manual steps as long as they meet the criteria that you’ve defined.

Follow along with this video to see how dynamic loading and Autofac module discovery work together in Blazor:

Advanced Scenario: Reflection-Based Type Discovery

If you’ve enjoyed this article, read the full article to cover reflection-based discovery and common pitfalls! Remember to subscribe to Dev Leader Weekly in order to have the full articles summarized and sent right to your inbox every week along with software engineering topics!