I’ve been reading about DI and the composition root. I’ve read in the article that only the application should have a composition root, not the libraries.
But let’s assume i have a reusable package with some interfaces and their implementation. I would like to bind that interface to the implementation. I think it would be cumbersome if the user has to do all this themselves.
Would it make sense to include an XML DI configuration file in the reusable module, which would be consumed and processed in the composition root?
But let’s assume i have a reusable package with some interfaces and their implementation. I would like to bind that interface to the implementation.
Why does your reusable package provide an interface and an implementation?
You can provide concrete classes if your reusable package is a library. As I write in DI-Friendly Framework:
A Library is a reusable set of types or functions you can use from a wide variety of applications. The application code initiates communication with the library and invokes it.
According to the Dependency Inversion Principle (DIP), the client defines the abstract interface of its dependencies. Any interface provided by the library would violate the DIP.
On the other hand, your reusable package can provide an abstraction (interface or base class) if you expect client code to supply an implementation. In that case, the package begins to look more like a framework, although there's probably a gray area there. Usually, in such cases, the package doesn't have to supply any implementations of the interface, or it can supply some for optional use.
There's probably some edge cases where both an interface and a (default) implementation shipping with the same package might make sense, but I don't see how it warrants more than the sort of default factory that Yacoub Massad recommends. You could make that API a Fluent Builder - that's a common pattern for that sort of scenario.
You can supply all the XML configuration files you wish if you don't want anyone to use your package.