simpleinjector / SimpleInjector

An easy, flexible, and fast Dependency Injection library that promotes best practice to steer developers towards the pit of success.
https://simpleinjector.org
MIT License
1.21k stars 153 forks source link

Using DI on a truly massive project (3000+ source files, multiple class libraries the works) #882

Closed astrohart closed 3 years ago

astrohart commented 3 years ago

I have a Visual Studio Solution with over 174 projects in it, and over 3000 source files. Basically I did as granular an extraction of code into separate class libraries as I could. This way, pieces of the software system can be reused by other projects of mine.

In the application's entry point, of course, I have to call Register methods on the DI container, like so:

using SimpleInjector;

static class Program
{
    static readonly Container container;

    static Program()
    {
        // 1. Create a new Simple Injector container
        container = new Container();

        // 2. Configure the container (register)
        container.Register<IOrderRepository, SqlOrderRepository>();
        container.Register<ILogger, FileLogger>(Lifestyle.Singleton);
        container.Register<CancelOrderHandler>();

        // 3. Verify your configuration
        container.Verify();
    }

    static void Main(string[] args)
    {
        // 4. Use the container
        var handler = container.GetInstance<CancelOrderHandler>();

        var orderId = Guid.Parse(args[0]);
        var command = new CancelOrder { OrderId = orderId };

        handler.Handle(command);
    }
}

I am a newbie to DI frameworks. Simple Injector sounds very appealing to utilize given its simplicity (to use a phrase). However, I am concerned -- do I have to add a line of code for each and every single interface/class in my huge software system? Short of writing a script to iterate over the entire solution and enumerate the classes and their matching interfaces, and then add Register calls to the Program constructor, is there a faster way?

dotnetjunkie commented 3 years ago

In Dependency Injection Principles, Practices, and Patterns, Mark Seemann and I describe the different configuration options you have when using a DI Container. The type of configuration you are referring to is called Code as Configuration. With Code as Configuration you express each mapping between an abstraction and a particular implementation explicitly and directly in code.

And other option, however, is Auto-Registration, which is a form of Convention over Configuration. Auto-Registration is the ability to automatically register implementations in a container by scanning one or more assemblies for implementations of desired abstractions, based on a certain convention.

For more on how to use Auto-Registration with Simple Injector, this documentation section is a good starting point.

If you're new to using DI Containers, I can certainly advise reading chapter 12 of my book, as it gives a decent introduction to DI Containers in general.

btw, whether or not a project is "massive" is very subjective. Although a solution with 3000 source files is certainly not small, i do not see this as "truly massive"; I often work on code bases that are much bigger.

astrohart commented 3 years ago

I appreciate the thoughtfully-worded and verbose response. I kind of already knew about the two different means of registering containers; it's on me for not having been more specific. I really should have asked, "Does Simple support Auto-Registration of objects?

astrohart commented 3 years ago

btw, whether or not a project is "massive" is very subjective. Although a solution with 3000 source files is certainly not small, i do not think this "truly massive" myself, and often work on code bases that are much larger.

I suppose it depends on one's point of view. My project as described above is the largest, most complex Visual Studio solution I've ever worked on, so, for me I suppose it is truly massive from that standpoint.