Inhaltsverzeichnis

C# Dependency Injection

C# Dependency Injection

Im folgenden programmieren wir ein kleines Beispiel Programm, um zu zeigen wie Dependency Injection funktioniert. Wir programmieren das Beispiel mit der Programmiersprache C#. Um die Dependency Injection in C# zu verwenden, nutzen wir die Autofac Bibliothek. Es geht in diesem Artikel, aber mehr um die grundsätzliche Idee, als die genaue Implementation.

Dependency Injection mit Autofac

Bei der Dependency Injection will man die Kopplung der Klassen untereinander verringern, man nennt dies Loose-Coupling. Ein Objekt soll möglichst wenig von den Anderen wissen. Dafür wird ein Objekt einer Klasse einer anderen Klasse zur Verfügung gestellt. Wir nutzen die Autofac Bibliothek. Die Bibliothek sorgt dabei dafür, das ein Objekt in den Konstruktor eingefügt, einer anderen Klasse eingefügt wird. Die beiden Klassen wissen nichts von einander. Die Abhängigkeit wird über die Dependency Injection eingefügt.

Im folgenden programmieren wir ein Wetter Vorhersage Programm. Dabei will eine Person wissen, wie viel Grad es morgen werden. Es gibt 2 unterschiedliche Vorhersage Angebote. Das eine kommt von einer Wetterstation, das andere von einem Satelliten.

Wetter Vorhersagen mit Dependency Injection

Zuerst erstellen wir ein neues Interface mit dem Namen IWeatherForecasting. Es hat folgende Methode: GetTemperature. Diese Methode gibt die Temperatur des nächsten Tages zurück. Dieses werden wir später mit der Autofac Bibliothek Dependency Injecten.


public interface IWeatherForecasting
{
    int GetTemperature();
}

Nun wollen wir zwei unterschiedliche Wetter Vorhersager haben, der "WeatherSatelite" und die "WeatherStation". Beide implementieren das Interface IWeatherForecasting.


public class WeatherSatellite: IWeatherForecasting
{
    public int GetTemperature()
    {
        return 20;
    }
}

public class WeatherStation : IWeatherForecasting
{
    public int GetTemperature()
    {
        return 22;
    }
}

Ok nun wollen wir die Wetter Vorhersage nutzen. Eine Person will wissen wie das Wetter wird, der Person ist egal, welche Art von Vorhersagen Methode genutzt wurde. Normalerweise würden wir nun im Konstruktor der Person, ein neue Instanz einer Wetter Vorhersage erstellen. Also erstellt die Person ein neues Objekt des Typs WeatherSatellite.


class Person
{
    private WeatherSatellite _weatherSatellite;
    public Person()
    {
        _weatherSatellite = new WeatherSatellite();
    }
}

UML Diagramm ohne Dependency Injection

In einem UML Diagramm sieht dies nun folgendermaßen aus:

Nun weiß die Person, aber welches Wetter Vorhersagen System verwendet wurde. Wir wollen das die Person möglichst unabhängig von der genauen Vorhersager Implemention ist. Sie soll beispielsweise auch noch herausfinden wie das Wetter wird, falls eine der Wetter Vorhersager nicht mehr funktioniert.

Daher sollte die Person nur mit dem Interface IWeatherForecaster arbeiten.

Nutzen des C# Interfaces


class Person
{
    private IWeatherForecasting _weatherSatellite;
    public Person()
    {
        _weatherSatellite = new WeatherSatellite();
    }
}

Das Problem ist aber das die Person nun immernoch selbst entscheidet, welcher Wetter Vorhersager genutzt werden soll. Daher übergeben wir einen Wetter Vorhersager als Parameter an die Person. Nun kann die Person nicht mehr entscheiden welchen Wetter Vorhersager er nutzen soll.

Wie sieht dies nun in unserem UML Diagramm aus ?

UML Diagramm ohne Dependency Injection mit Interface

Deswegen übergeben wir an den Konstruktor der Person einen IWeatherForecating Objekt.


class Person
{
    private IWeatherForecasting _weatherForecasting;
    public Person(IWeatherForecasting weatherForecasting)
    {
        _weatherForecasting = weatherForecasting;
    }
}

Nun initialisieren wir eine Person in der Main Methode des Programms. Nun nutzen wir die Bibliothek Autofac von C# um die Objekte die wir benötigen automatisch initialisieren zu können. Zuerst müssen wir uns die Autofac Bibliothek installieren. Danach müssen wir zu der Datei "using Autofac" hinzufügen. Danach erstellen wir einen Autofac ContainerBuilder, diesem sagen wir, welche Objekte dieser Injecten soll. Wir legen fest, das wir bei dem Interface IWeatherForecaster immer einen WeatherSatellite erstellt werden soll.

Danach bauen wir den Container, beginnen wir den Lifetime Scope. Jetzt können wir über den Resolve Funktion ein Objekt vom Typ IWeatherForecasting geben lassen, ohne das es uns interessiert, von welchem Sub-Typen der WeatherForecaster ist.

Autocfac Dependency Injection mit Container


class Programm
{
    public static void Main()
    {
        var builder = new ContainerBuilder();
        
        builder.RegisterInstance(new WeatherSatellite())
            .As<IWeatherForecasting>();
        
        var container = builder.Build();
        using(var scope = container.BeginLifetimeScope())
        {
            var weatherForecaster = scope.Resolve<IWeatherForecasting>();
            var person = new Person(weatherForecaster);
        }
    }
}

Jetzt ist der Person nun egal, welches IWeatherForecastingObjekt es nutzt. Wir könnten nun ganz einfach die Klasse WeatherSatellite löschen. Danach müssten wir nun unserem Autofac Container sagen, das er nun ein Objekt vom Typ WeatherStation nutzen soll. Dies können wir auch im UML Diagramm sehen.

UML Diagramm mit Dependency Injection

Person Auch Über Autofac Injecten

Man kann auch zusätzlich noch Person zu unserem Autofac Container hinzufügen. Dann müssen wir garnicht festlegen, dass Person ein WeatherForecasting Objekt verwenden muss. In dem Programmauschnitt sehen Sie wie dies funktioniert.


class Programm
{
    public static void Main()
    {
        var builder = new ContainerBuilder();
        
        builder.RegisterInstance(new WeatherSatellite())
            .As<IWeatherForecasting>();
        builder.RegisterInstance(new Person(new WeatherSatellite()));
        var container = builder.Build();
        using var scope = container.BeginLifetimeScope();
        var person = scope.Resolve<Person>();
    }
}

Fazit

Wie man hoffentlich sehen konnte, hilft uns Dependency Injection schönren, leichter erweiterbaren Programmcode zu schreiben. Dependency Injection tut dies, in dem es die Abhängigkeiten von Objekte untereinander injected, so dass de Klassen nur noch über Loose Coupling aneinnder gebunden sind. Es ist zu empfehlen Dependency Injection zu nutzen, wenn man mehrere Klassen hat welche voneinander abhängig sind und man plant das Programm zu erweitern.

No items found.

Häufig gestellte Fragen:

Weitere Artikel:

Tobias Bück

Ich bin einer der Geschäftsführer der Softoft GbR und ich studiere Wirtschaftsinformatik. Aktuell beschäftige ich mich viel mit dem OTOBO-Helpdesk.
tobias.bueck@softoft.de
Zuletzt Aktualisiert
7.7.2022

Kontakt:

Gerne vereinbaren wir ein Beratungsgespräch

info@softoft.de
Wir Freuen Uns Über Deine Nachricht!
Bitte gebe Kontaktdaten an über die wir dich erreichen können
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Email Schreiben