Hacker News new | past | comments | ask | show | jobs | submit login

It's really very simple, no you don't need to pass around a factory object.

You just have a class/classes that construct/wire all of your singleton objects and passes the required dependencies into their respective constructors as necessary.

Here is a contrived example of what the wiring code might look like for a web app that uses a database.

    public static void main(String[] args) {
        MyConfig config = readConfigFile();
        DatabaseConnection dbConn = new DatabaseConnection(config.dbHost(), config.dbPort());
        UserDao userDao = new UserDao(dbConn);
        UserController userController = new UserController(userDao);
        List<Controller> controllers = List.of(userController);
        WebServer webServer = new WebServer(config.listenPort(), controllers);
        webServer.runAndBlock();
    }



How is it better to make a dev write out that plumbing and others reread it? I’m made of meat, so I want to automate everything we safely can.


Advantages:

- Don't need to depend on a DI library, makes code more modular and portable.

- Faster application initialization time.

- Easy to navigate and understand relationships between classes, good IDE support.

- Easier to break apart and test parts of the application.

- Easy to understand, don't need to learn the intricacies of a complex DI framework.

I'm not saying there is no place for DI frameworks, although I do think they are overused.


> don’t need to learn

I know it is a nitpick, but I see this way more often than I should as a main reason to prefer alternatives.

Finding out what gets injected is not particularly hard, especially when only the basic capabilities of spring’s DI is used. In that case it will be almost always the single implementing class of the given type.


So if you are making any kind of reusable design, you cannot annotate your classes with @Bean anymore. Instead you will make an @Configuration (like spring boot auto configuration) that by discretion may pull in some more general (not @Configuration annotated) reusable configuration. Since some classes will be considered implementation details, you won't want to expose those into the dependency injection container of spring (since that is equivalent to making them public, people will inject them and depend on them!). So instead you will only create them inside your own @Configuration and pass them directly when generating an @Bean from a method.

Congratulations, your @Configuration is manual dependency injection. That is easy enough. Why did we need inversion of control over the dependency injection in the first place? It isn't immediately obvious to new engineers what aspect of the @Autowired is dependency injection and which aspect is inversion of control. Many of us don't see much of a benefit to the inversion of control if you are taking care of your application's hygiene in the first place.


A @Bean method is a signal that a class is so complicated that Spring can’t figure out how to create a valid instance after @Import or @ComponentScan. For limiting use, package-private types and methods are better than creating components yourself and reinventing pieces of Spring like @Profile and @Value and @Scope.


You’re reading and writing the “plumbing” no matter what you do. So, does it matter if you are writing a config file or Java code?


Unless WebServer is the only class that needs dependencies you're either going to have to pass those dependecies repeatedly from class to class or you're going to have a global factory that provides the dependencies to everybody.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: