Beispielbeispiel mit Asp.net-Kern
Link zum aufgezeichneten Video: https://www.youtube.com/watch?v=oVj1IHw8GLU
OverviewOfDI: https://github.com/sandeepmvn/DependencyInjectionRepository/blob/master/OverviewOfDI.txt
ASP.NET Core unterstützt das Softwareentwurfsmuster Dependency Injection (DI), eine Technik zum Erreichen der Inversion of Control (IoC) zwischen Klassen und ihren Abhängigkeiten.
Durch den IoC-Container können wir dies erreichen
Im Asp.net-Kern verfügt der IoC-Container über integrierte Schnittstellen.
Der folgende DI-Lebenszyklus wird sein
Grundsätzlich gibt es in ASP.NET Core zwei Arten von Diensten:
Framework-Dienste: Dienste, die Teil des ASP.NET Core-Frameworks sind, wie IApplicationBuilder, IHostingEnvironment, ILoggerFactory usw.
Anwendungsdienste: Die Dienste (benutzerdefinierte Typen oder Klassen), die Sie als Programmierer für Ihre Anwendung erstellen.
Asp.Net Core MVC-Controller fordert Abhängigkeiten explizit über Konstruktoren an: 1. Konstruktorinjektion, 2. Methodeninjektion (Aktionsebene), 3. Propery-Injektion (nicht unterstützt), 4. View-Injektion
Konstruktorinjektion: – Dienste werden als Konstruktorparameter hinzugefügt und lösen den Dienst zur Laufzeit aus dem Dienstcontainer (IServiceCollection – DiContainer) auf. Dienste werden normalerweise mithilfe nicht-konkreter Klassen (Schnittstellen) definiert.
Methodeninjektion: – Die Verwendung des Attributs [FromService] ermöglicht die direkte Injektion eines Dienstes in eine Aktionsmethode, ohne die Controller-Injektion zu verwenden
Property-Injection Derzeit unterstützt der integrierte IOC-Container (Asp.net-Kern) keine Property-Injection. Hierfür können Sie sich für integrierte Service-Container (IOC) von Drittanbietern entscheiden.
View-Injection Mit der [Inject]-Direktive können Sie den Dienst direkt in die Ansichtsseite einfügen, ohne einen Controller oder eine Methodeninjektion zu verwenden
Der integrierte IoC-Container unterstützt drei Arten von Lebensdauer:
Im Beispielbeispiel definiert die Dienstschnittstelle „IMyDependency“ die Methode „WriteMessage“.
public interface IMyDependency
{
void WriteMessage(string message);
}
Diese Schnittstelle wird durch einen konkreten Typ, MyDependency, implementiert:
public class MyDependency : IMyDependency
{
public void WriteMessage(string message)
{
Console.WriteLine($"MyDependency.WriteMessage Message: {message}");
}
}
Registriert nun den Dienst „IMyDependency“ mit dem konkreten Typ „MyDependency“ (in Startup.cs).
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.Add(new ServiceDescriptor(typeof(IMyDependency), new MyDependency()));
}
}
Hier wird die Add()-Methode der Instanz „IServiceCollection“ verwendet, um einen Dienst bei einem IoC-Container zu registrieren. Der „ServiceDescriptor“ dient zur Angabe der Art des Dienstes und der konkreten Implementierung. Dadurch wird unser Dienst im Container standardmäßig als „Singleton“ registriert.
Lassen Sie uns nun Dienste mit unterschiedlichen Lebenszeiten einfügen
Singleton (Anwendungsfall: wenn wir einen Staatsdienst erstellen müssen):
Services.Add(new ServiceDescriptor(typeof(IMyDependency), new MyDependency(),ServiceLifetime.Singleton));
Vorübergehend (Anwendungsfall: wenn wir einen zustandslosen Dienst erstellen müssen):
Services.Add(new ServiceDescriptor(typeof(IMyDependency), new MyDependency(),ServiceLifetime.Transient));
Geltungsbereich (Anwendungsfall: Datenbankdienst):
Services.Add(new ServiceDescriptor(typeof(IMyDependency), new MyDependency(),ServiceLifetime.Scoped));
Wir können die Dienste auch mithilfe integrierter Erweiterungsmethoden einbinden
Singleton
Services.AddSingleton
Vorübergehend
Services.AddTransisent
Zielfernrohr
Services.AddScoped
öffentliche Klasse HomeController: Controller { private readonly IMyDependency _service;
public HomeController(IMyDependency service)
{
_service = service;
}
public IActionResult Index()
{
_service.WriteMessage("Constructor level injection")
return View();
}
}
public class HomeController : Controller
{
//Fromservice attribute
public IActionResult Index([FromService]IMyDependency service)
{
service.WriteMessage("Action level injection")
return View();
}
}
öffentliche Klasse HomeController: Controller {
public IActionResult Index()
{
return View();
}
}
In Index.cshtml
@{ ViewData["Title"] = "Homepage"; }
//using Inject directive
@inject IMyDependency service
//code block
@{
service.WriteMessage("View level Injection");
}
öffentliche Klasse HomeController: Controller {
public IActionResult Index()
{
var services = this.HttpContext.RequestServices;
var dependencyservice = (IMyDependency)services.GetService(typeof(IMyDependency));
dependencyservice.WriteMessage("without injection, accessing dependent services");
return View();
}
}