9.2. Dependency Injection

One of the best ways to limit dependencies between libraries is by using "dependency injection," which, in short, means trading compile-time dependencies for runtime dependencies by using configuration.

If your code is already factored to use interfaces, dependency injection is as simple as loading libraries dynamically based on some form of configuration. The easiest way to do that (at least in C#) is to enhance the factory class you looked at earlier in the chapter. Instead of loading the real logging implementation class in compile-time code like this:

public static class LoggerFactory
{
    private static readonly MyLogger logInstance = new MyLogger();

    public static ILogger Create()
    {
        return logInstance;
    }
}

You can load it through dependency injection. First, you need some form of configuration:

<?xml version="1.0" encoding="utf-8" ?>
 <configuration>
   <appSettings>
     <add key="LimitingDependencies.ILogger" value="LimitingDependencies.MyLogger"/>
   </appSettings>
</configuration>

This is about the simplest way to configure dependency injection in .NET. It maps the interface type to the concrete type that implements the interface. The factory class reads the configuration and uses it to create the concrete type as shown in the following example.

public class DependencyInjector { public static object GetAnInterface(Type interfaceType) { string interfaceName = interfaceType.FullName; string typeName = ConfigurationManager.AppSettings[interfaceName]; Type t = ...

Get Code Leader: Using People, Tools, and Processes to Build Successful Software now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.