This class is called Greeter
. Its responsibility is to output a greeting. It has two dependencies. It needs something that will give it the greeting to output, and then it needs a way to output that greeting. Those dependencies are both described as interfaces, IGreetingProvider
and IGreetingWriter
. In this example, those two dependencies are "injected" into Greeter
. (Further explanation following the example.)
public class Greeter
{
private readonly IGreetingProvider _greetingProvider;
private readonly IGreetingWriter _greetingWriter;
public Greeter(IGreetingProvider greetingProvider, IGreetingWriter greetingWriter)
{
_greetingProvider = greetingProvider;
_greetingWriter = greetingWriter;
}
public void Greet()
{
var greeting = _greetingProvider.GetGreeting();
_greetingWriter.WriteGreeting(greeting);
}
}
public interface IGreetingProvider
{
string GetGreeting();
}
public interface IGreetingWriter
{
void WriteGreeting(string greeting);
}
The Greeting
class depends on both IGreetingProvider
and IGreetingWriter
, but it is not responsible for creating instances of either. Instead it requires them in its constructor. Whatever creates an instance of Greeting
must provide those two dependencies. We can call that "injecting" the dependencies.
Because dependencies are provided to the class in its constructor, this is also called "constructor injection."
A few common conventions:
private
fields. As soon as the class is instantiated, those dependencies are available to all other non-static methods of the class.private
fields are readonly
. Once they are set in the constructor they cannot be changed. This indicates that those fields should not (and cannot) be modified outside of the constructor. That further ensures that those dependencies will be available for the lifetime of the class.