Willkommen bei ASP.NET Zone. Anmelden | Registrieren | Hilfe

DI / IoC Container LightCore Teil 1: Einführung

LightCore DI/Ioc ContainerIn einer mehrschichtigen Architektur (Oft verwendet die 3-Tier/3 Schichten Architektur) wird es immer wichtiger Abhängigkeiten zu minimieren.
In großen Projekten kann es leicht vorkommen, dass ein Chaos von Abhängigkeiten entsteht.
Nicht alle Abhängigkeiten lassen sich vermeiden, aber viele sind unnötig. Vor allem falsche können die Entwicklung eines Projektes aufhalten.

In den diversen Schichten(Data, Web, …)  den Code unabhängig voneinander zu halten, hilft dem gesamten Prozess ungemein.
Eine Technik, um die Kopplung so gering wie möglich zu halten ist ein Inversion of Control Container. (IoC Container)

Mehr dazu in einem Artikel von Martin Fowler: Inversion of Control Containers and the Dependency Injection pattern

Genauer eingegangen wird auf den frischen IoC Container „LightCore“ von Peter Bucher.
Wie das Wort schon sagt, ist dieser lightweight und kann mit Performance und Einfachheit punkten, muss aber nicht in Sachen Features einpacken.

Eine Feature List von Lightcore finder sich hier.
Weiter Argumente die für LightCore sprechen finden sich in einem Blogeintrag von Golo Roden.

1. LightCore – Einführung
2. LightCore – Registrierung über Xml Module
3. LightCore – Registrierung von Generics

Der Erste Teil der Einführung wird ein einfaches Beispiel mit LightCore behandeln.
Um etwas tiefer in die Materie einzusteigen wird im zweiten Teil gezeigt, wie man mit LightCore die Unabhängigkeit einer 3-Schichten Architektur verbessern kann, wie man mit dem integrierten Registrations-Modul über Xml bzw. XAML arbeitet und wie man Generics registrieren kann.

Einbinden von Lightcore

Wer auf die Entwicklungsversion zugreifen will, muss sich diese mit Subversion laden.
Diese wurde vor allem laut den Prinzipien von CCD (Clean code development) und mit einer kompletten Unit Test Abdeckung entwickelt – somit auf jeden Fall einen Blick Wert!

Für das folgende Beispiel reichen die DLLs, die es ebenfalls hier zum Download gibt.



Als Erstes müssen die gewünschten Kontrakte (Schnittstellen) registriert werden. Dies kann über zwei Varianten erfolgen:
  • Registrierung über Code
  • Registrierung über eine XML Konfigurations- Datei
Wenn die Registrierung codeseitig gewünscht ist, sollte dies in der Globalen Anwendungsdatei (Global.asax) erfolgen

Der Container wird als static member deklariert

private static IContainer _container;

In der Methode Application_Start wird der IoC Container initialisiert.

protected void Application_Start(object sender, EventArgs e)
{
    var builder = new ContainerBuilder();


Es gibt mehrere, optionale Features, die bei der Registrierung angegeben werden können. Für das Beispiel wird ein Logger registriert.

// Einfache Registrierung
builder.Register<ILogger, Logger>();
// Angabe eines Namen, um eine klare Trennung zu behalten
builder.Register<ILogger, Logger>().WithName("MyLogger");
// Angabe einer Gruppe, um bestimmte Kontrakte zu sammeln
builder.Register<ILogger, Logger>().WithGroup("MyGroup");
// Angabe von Argumenten für den Konstruktoraufruf
builder.Register<ILogger, Logger>().WithArguments("Test Argument", true);
// Gemischte Angabe
builder.Register<ILogger, Logger>().WithName("MyLogger").WithArguments("Test Argument", true);


Wenn alles registriert ist, den Container noch erstellen:

_container = builder.Build();

Die Registrierten Kontrakte können manuell über resolve aufgelöst werden

// Einfach
var myLogger = _container.Resolve<ILogger>();
//Mit Namen
var myLogger = _container.Resolve<ILogger>("MyLogger");


Lifecycle

Der Lebenszyklus besagt, ob bei jedem Anfordern einer Instanz über <Container>.Resolve<Icontract>() ein neues Objekt erstellt wird (Identisch zum new-Operator), oder das Objekt wiederverwendet werden kann.

Für die Wiederverwendung von Instanzen werden Folgende Lebenszyklen unterstützt, wobei auch weitere Lebeszyklen geschrieben werden können:
  • Transient
  • Singleton
  • ThreadSingleton
  • HttpRequest
Als Standard wird der transient Lebenszyklus verwendet. Dies besagt, dass bei jedem Aufruf eine neue Instanz der Klasse erstellt wird. Singleton würde bedeuten, dass eine einzige Instanz pro Anwendung erzeugt wird.

Der Lebenszyklus wird einmal pro Kernel wie folgt gesetzt:

builder.DefaultControlledBy<TransientLifecycle>();

Klarer weiße kann man den Lebenszyklus auch pro Registration angeben:

builder.Register<ILogger, Logger>().ControlledBy<SingletonLifecycle>();

Die Lebenszyklen können ohne Probleme beliebig erweitert werden.


Das Ergebnis

Angenommen wir haben den Logger registriert und möchten nun die Instanz in einer normalen Page Klasse

public partial class _Default : System.Web.UI.Page
{
    public ILogger Logger
    {
        get;
        set;
    }


In der Page Load wird der logger nun benötigt:

protected void Page_Load(object sender, EventArgs e)
{
    ILogger logger = this.Logger;
    logger.log("Page Loaded!");
}


Und wie von Magie haben wir eine Instanz der Klasse ohne direkte Erstellung auf der aktuellen Seite.

Was ist passiert?
Ein http Modul in Lightcore macht automatisch ein resolve auf die Eigenschaften, die registriert sind. Somit entfällt die manuelle Auflösung und man ist komplett vom Dependency Injection Container unabhängig.

Damit das auch klappt, muss das Modul in der Web config im Abschnitt <httpModules> hinzugefügt werden:

<httpModules>
    ...
    <add name="LightCoreDependencyInjectionModule" type="LightCore.Integration.Web.DependencyInjectionModule, LightCore.Integration.Web, Version=1.0.0.0, Culture=neutral"/>
</httpModules>


Mit ein bisschen Kreativität kann diese Vorgehensweise in allen möglichen Stellen eingesetzt werden – und schon ist man ein klein wenig Unabhängiger!

Der zweite Teil des Posts wird mit folgenden Themen in Kürze folgen: Registration über Web/App Config oder eigene Konfigurationsdatei, Einsatz in einer 3 Schichten Architektur und Registrierung von Generics!

Anbei gibt’s wie immer das oben angeführte Beispiel!

Veröffentlicht Samstag, 16. Januar 2010 17:03 von Roberto
Abgelegt unter: , ,

Attachment(s): LightCore.DemoPartOne.zip

Kommentare

# Roberto's Blog : DI / IoC Container LightCore Teil 2: Registrierung &#252;ber Xml Modul

# DI / IoC Container LightCore

Sie wurden gekickt (eine gute Sache) - Trackback von dotnet-kicks.de

Dienstag, 23. Februar 2010 10:42 by dotnet-kicks.de

# re: DI / IoC Container LightCore Teil 1: Einführung

Interessante Serie - merci ;-)

Dienstag, 23. Februar 2010 10:43 by Rene Drescher-Hackel

# BASTA! Spring 2010: Das wars …

Ich habe es tatsächlich geschafft und über jede besuchte Session einen Beitrag geschrieben und ich habe

Montag, 1. März 2010 10:32 by Jürgen Gutsch
Anonyme Kommentare sind nicht zugelassen