Reputation: 414
I've a root project (root
), some modules (A
, B
), and these modules have some external dependencies (Z
). I'm using an IoC container.
I'm using C# here, but is a generic pattern question. Let say that my container is services
, and I can initialize IoC configuration with use of extension methods. So in root
project I'm writing:
services.AddModuleA();
services.AddModuleB();
On module A
I've this method:
public static void AddModuleA(this IServiceCollection services)
{
// Init module internal services.
//services.AddScoped<IA1Service, A1Service>();
//...
// Init module external dependencies.
services.AddDependencyZ();
}
On module B
I've a similar method:
public static void AddModuleB(this IServiceCollection services)
{
// Init module internal services.
//...
// Init module external dependencies.
services.AddDependencyZ();
}
Obviously Z
dependency was already been added, so this tells me that I should not configure it inside a module extension method, and I should rather declare its configuration in root
project:
services.AddModuleA();
services.AddModuleB();
services.AddDependencyZ();
But doesn't this break the Least Knowledge principle? Importing and configuring a module A
(or B
) will bring to a cascade explicit declaration of all dependency configurations.
And related question, is declaring the extension methods AddModuleA()
and AddModuleB()
a bad pattern at all? Could be a better idea to configure directly on root
only services that I will use?
And in this case (a bit extreme), what about config of internal use only class?
Upvotes: 2
Views: 209
Reputation: 233317
Supposing that those extension methods are defined in your application's Composition Root, why don't you just remove the call to AddDependencyZ
from within AddModuleA
and AddModuleB
?
public static void AddModuleA(this IServiceCollection services)
{
// Init module internal services.
//services.AddScoped<IA1Service, A1Service>();
//...
}
public static void AddModuleB(this IServiceCollection services)
{
// Init module internal services.
//...
}
You would then, as you write, configure the container in the Composition Root (this is the Register phase in the RRR pattern):
services.AddModuleA();
services.AddModuleB();
services.AddDependencyZ();
Does this break the Least Knowledge principle? Yes, it does, but that's one of the many drawbacks of using a DI Container.
I recommend Pure DI instead of using a DI Container. That would make the problem disappear because all the code in the OP would be redundant.
Upvotes: 2