Coupling describes how much a class depends on other classes to do its job. Loosely coupled code needs to know fewer details about the components it uses. That makes it easier to change or test one part of an application without changing another. section 8.2
Listing 8.3 Sending email without DI when you create dependencies manually
string RegisterUser(string username)
{
var emailSender = new EmailSender( #1
new MessageFactory(), #2
new NetworkClient( #3
new EmailServerSettings #4
( #4
Host: "smtp.server.com", #4
Port: 25 #4
)) #4
);
emailSender.SendEmail(username); #5
return $"Email sent to {username}!";
}
Here, the registration handler creates an email sender and all its dependencies. If the sender needs another dependency, the handler must change too. This is tight coupling: handling a registration requires knowledge of how email delivery is assembled. section 8.1 section 8.2
Dependency injection removes that construction work from the handler: it declares the service it needs and receives it. Depending on an interface reduces coupling further. The handler can call the interface’s method without knowing which implementation it received, so a test can supply a stub or mock instead of sending a real email. section 8.1 section 8.2
Listing 8.5 Using interfaces with dependency injection
string RegisterUser(string username, IEmailSender emailSender) #1
{
emailSender.SendEmail(username); #2
return $"Email sent to {username}!";
}
The handler accepts an email-sending interface and uses its method. Its business task stays visible, while the choice of implementation is kept elsewhere. section 8.2
Loose coupling also matters between larger parts of a web application. With separation of concerns, a view generates HTML, application logic performs business work, and a page handler validates the request and chooses a response. Clear boundaries help keep a UI change from requiring a business-logic change. section 13.4.4
A change that reached too far
In one web app, business-layer class names were used to generate HTML. Renaming a misspelled class broke the website in users’ browsers. The problem was not the rename itself, but the hidden dependence between business logic and HTML generation. section 13.4.4
Aim to reduce coupling between logically separate parts, not to add wiring for its own sake. Dependency injection can be unnecessary overhead in a simple application; its value grows as dependencies and changes become harder to manage. section 8.1 section 13.4.4
















