There are two kinds of relationships between classes:
Inheritance (is-a)
Composition (has-a)
This post is based on an instructional video by Mosh Hamedani at Udemy.com. Suppose we are building an application that has many parts to it. One of the parts, a logger, is responsible for logging information to a text file. We have two other parts of the application that need to use the logger. We have a DbMigrator and we have an Installer. Both of these have a relationship to the logger class. They both use it. This is nothing new here in C#. We don’t need any special syntax like we need with inheritance. One class contains another. We can say that a car has an engine. The engine is inside the car.
Generally, developers favour composition over inheritance. For an example of inheritance we have the post called C# Interfaces Extensibility.
With composition we get code re-use, as we get with inheritance. Composition is more flexible and a means to designing loosely coupled applications. Here is a UML diagram showing our example project.
First, here is our logger code. It just has a method that writes to the console so we can see that it was executed.
Below is our program. Notice that the first three lines of code create a dbMigrator and an Installer. In the first of the three lines, we create a logger object and pass it all in one line of code. In the second line of code, we create a new Logger object called logger. In the third line, we pass the logger object.
In our two classes that use the logger, they each have a private field that contains the logger. That field is of the type of our class: Logger. To say it again, they have a private field that contains the custom class logger. Also, they each have a constructor that we wrote. The constructor requires a logger object that is used to initialize the private field. The Logger is a private field in the Installer and the DbMigrator.
The related class is a private filed in the composite class.