In Anwendungen mit mehrschichtigen Architekturen ist es wichtig, dass es wenig Abhängigkeiten von anderen Komponenten gibt. Um solche Abhängigkeiten zu vermeiden bzw. zu verringern, gibt es sogenannte Inversion of Control Container (IoC Container). Mehr zum Thema IoC Container findet ihr hier
Nun möchte ich euch gerne den IoC Container "LightCore" von Peter Bucher anhand einer Demoanwendung demonstrieren.
Die LightCore.Demo Anwendung ist eine Windows Forms Applikation, die Kundendaten an ein DataGridView binden soll. Nun habe ich zum Projekt mehrere Komponenten hinzugefügt:
Core:
Besteht aus dem LightCore IoC Container, welcher vom ModulManager verwaltet wird. Zusätzlich werden die Schnittstellen ICustomerService, ICustomerRepository für den Business- und DataLayer definiert.
Framework:
Hat eine Initializer Klasse, die alle Module beim ModulManager registriert, diese wird einmalig von der UI aufgerufen.
BusinessLayer:
Enthält ein CustomerService
DataLayer:
Enthält ein CustomerRepository, sowie ein MockCustomerRepository für den Zugriff auf Mockdaten.
Solution Explorer

Architektur

Wie man sehen kann, hat der BusinessLayer (BL) keine direkte Verbindung mit dem DataLayer (DL). Doch wie soll der CustomerService an die Daten kommen?
Dies geschieht durch Dependency Injection, dabei wird dem Konstruktor vom CustomerService ein ICustomerRepository "injiziert".
public class CustomerService : ICustomerService
{
private ICustomerRepository<ICustomerData> _repository;
public CustomerService(ICustomerRepository<ICustomerData> repository)
{
_repository = repository;
}
public IList<ICustomerData> GetAllCustomer()
{
return _repository.GetAllCustomer();
}
}
Kommen wir nun zur Registrierung der Module mit dem IoC Container.
Sobald die UI startet, wird der Initializer aufgerufen, welcher dann die Module beim IoC Container registriert. Hierbei muss das Interface und die Implementierung beim Container registriert werden.
ModulManager.Register<ICustomerService, CustomerService>();
Ein netter Vorteil dabei ist, es lässt sich mit einer Codezeile eine andere Implementierung registrieren, so kann man jederzeit eine Repository durch eine MockRepository austauschen. So hab ich die CustomerRepository welche noch keine Implementierung hat, durch die MockCustomerRepository ausgetauscht.
Nachdem alle Komponenten registriert wurden, muss der IoC Container erstellt werden, dies geschieht mit Build()
Initializer
public class Initializer
{
public static void Initialize()
{
ModulManager.Register<ICustomerRepository<ICustomerData>, MockCustomerRepository>();
//ModulManager.Register<ICustomerRepository<ICustomerData>, CustomerRepository>();
ModulManager.Register<ICustomerService, CustomerService>();
ModulManager.Build();
}
}
ModulManager
using LightCore;
namespace Core
{
public class ModulManager
{
private static readonly ContainerBuilder _builder;
private static IContainer _container;
static ModulManager()
{
_builder = new ContainerBuilder();
}
public static void Register<TContract, TImplementation>() where TImplementation : TContract
{
_builder.Register<TContract, TImplementation>();
}
public static T Get<T>()
{
return _container.Resolve<T>();
}
public static void Build()
{
_container = _builder.Build();
}
}
}
In der UI soll auf eine Instanz des CustomerService zugegriffen werden, um die Kundendaten an das DataGridView zu binden. Hierbei arbeitet man nur gegen Interfaces, so wird ein ICustomerService deklariert, welcher dann vom ModulManager eine Instanz erhält.
ICustomerService service = ModulManager.Get<ICustomerService>();
dataGridView1.DataSource = service.GetAllCustomer();
dataGridView1.AutoGenerateColumns = true;
Und so sieht dann unsere UI aus, nachdem die Mockdaten an das DataGridView gebunden wurden...

DOWNLOAD
LightCore.Demo.zip (79,81 kb) [Downloads: 441]