home producten

Delta-N PicoContainer

Het eerste component dat beschikbaar gesteld wordt is de PicoContainer, dit component is afkomstig uit de Java open source community. De java implementatie van de PicoContainer is door medewerkers succesvol gebruikt in een java applicatie. Door deze implementatie werd de kracht van dit mechanisme in een service-oriented architectuur snel duidelijk en ontstond de behoefte aan een identiek component voor de .NET omgeving.

Achtergrond

Developers die bezig waren met een intern java-project gebruikten de java-implementatie van de PicoContainer en kwamen tot de conclusie dat deze uiterst nuttig was bij het implementeren van systemen die loosely coupled zijn zoals wordt gepromoot door de architectuur die Delta-N heeft geadopteerd. De originele java-implementatie is beschikbaar op PicoContainerJava. Deze site wordt onderhouden door de developers en makers van de PicoContainer. De site wordt ten zeerste aanbevolen voor gedetailleerde informatie over de PicoContainer.

Omdat er helaas geen implementatie voor .NET beschikbaar was, heeft Delta-N de versie naar .NET geport.

Wat is de PicoContainer

PicoContainer is een kleine en eenvoudige container voor willekeurige componenten/services. Het belangrijkste doel van de PicoContainer is het loskoppelen van de gebruiker van een service/component en de implementatie van een component. De componenten worden in de PicoContainer geregistreerd, op basis van interface en implementatie stelt de PicoContainer de implementaties van de gevraagde componenten bij aanmaak ter beschikking.

Een component kan in de PicoContainer worden gebruikt zonder aanpassingen. In de service hoeven geen metagegevens te worden vastgelegd: niet in XML en ook niet met behulp van attributes. En als laatste maar niet als minst belangrijke: een component dat voor de PicoContainer wordt gebouwd, kan zonder de PicoContainer worden gebruikt voor een klassieke hard-coded deployment.

Wat is uw belang hierbij? Als u de PicoContainer gaat gebruiken, wordt uw code modulair (loosely coupled), eenvoudig te testen, flexibel te configureren, gemakkelijk te onderhouden en uit te breiden.

Meer achtergrond

De PicoContainer is een implementatie van een pattern genaamd Inversion of Control (IoC) of Dependency Injection. Er bestaat nog een andere naam voor dit pattern, een naam die ook de beste omschrijving geeft: "The Hollywood Principle" ("Don't call us we'll call you").

Als u software implementeert die gebruik maakt van dit pattern, krijgt u code die extreem ontkoppeld is (loosely coupled).

In de traditionele situatie moest een component dat voor het functioneren afhankelijk is van een ander component op zoek gaan naar een verwijzing van het component waarvan het afhankelijk is. Deze verwijzing kwam dan tot stand via een service factory of, nog erger, door direct een instantie aan te maken van het component waarvan het afhankelijk is. Bij gebruikmaking van IoC is dit allemaal niet het geval. Het component verklaart eenvoudigweg dat er een andere component nodig is en het betreffende component wordt vervolgens extern geleverd.

Problemen met service factories

Deze aanpak ontkoppelt de implementatie en de interface waardoor loose coupling tussen componenten wordt gerealiseerd. Deze aanpak kent echter wel een probleem. Om de componenten geïsoleerd te testen, dient de factory in runtime vervangen te worden door een mock factory. Dit is weliswaar mogelijk, maar in de meeste gevallen moeten componenten dan specifiek voor het testen worden gemodificeerd. Er zal dus code moeten worden ontwikkeld ten behoeve van het in samenhang testen van componenten; code die geen functie meer heeft in de runtime-versie van de toepassing.

Een overmatig gebruik van dit pattern leidt tot applicaties die slecht zijn ontworpen en lastig te onderhouden zijn.

Componenten hard coderen

Bij deze aanpak verdwijnen alle voordelen van het gebruik van interfaces en ontstaat een sterk gekoppelde applicatie.

Elke applicatie die op deze wijze wordt gebouwd, laat de voordelen van een op componenten/services gebaseerde applicatie onbenut. Zodra een component wordt gewijzigd of toegevoegd, moet de applicatie opnieuw worden gebouwd.

De PicoContainer gebruiken

Vereiste services publiceren

PicoContainer maakt gebruik van constructors voor het vastleggen van afhankelijkheden.

De parameters van de constructors worden gebruikt voor het identificeren van de afhankelijke componenten voor de class. Meerdere constructors zijn toegestaan. PicoContainer zal de "greediest" constructor (de constructor die de meeste parameters accepteert) gebruiken om de component te initialiseren.

Een eenvoudig voorbeeld:

public class ProductManager {

ImageManager imageManager = null;

public ProductManager(ImageManager imageManager) {

this.imageManager = imageManager;

}

}

// The ImageManager

public class ImageManager { }

Deze voorbeelden tonen een ProductManager die afhankelijk is van een component genaamd ImageManager (voor een beter overzicht worden er geen interfaces gebruikt. De PicoContainer ondersteunt zowel interfaces als classes)

De ProductManager gebruiken zonder de PicoContainer

De ProductManager is eenvoudig zonder de PicoContainer te gebruiken. Het volstaat een instantie van de ProductManager aan te maken en deze aan de ImageManager te geven.

new ProductManager( new ImageManager() );

Dit is een prachtige oplossing voor unit testing omdat met deze aanpak de ProductManager kan worden getest los van de afhankelijke componenten. Het enige dat hiervoor nodig is, is het doorgeven van een MockObject aan de ImageManager.

De ProductManager gebruiken met de PicoContainer

De PicoContainer kan vervolgens worden gebruikt om de afhankelijkheden op te lossen.

PicoContainer container = new AnyPicoContainer();

// Register the ProductManager and the ImageManager

container.RegisterComponent(typeof(ProductManager));

container.RegisterComponent(typeof(ImageManager));

// Now get instance of a initialized ProductManager

ProductManager mgr = (ProductManager)container.GetComponent(typeof(ProductManager));

Dit voorbeeld laat zien hoe eenvoudig het is de PicoContainer te gebruiken om afhankelijkheden tussen componenten op te lossen.

Dit voorbeeld laat ook zien dat het niet nodig is zelf een instantie aan te maken van de ImageManager. Deze afhankelijkheid wordt namelijk automatisch opgelost door de container. Dit voorbeeld toont de meest eenvoudige toepassing van de PicoContainer. De implementatie van de PicoContainer bevat echter geavanceerde scenario's zoals automatische singleton-versies van services en life cycle support.

De PicoContainer configureren

In het ontwerp van de PicoContainer is geen functionaliteit ingebouwd voor configuratie. De namespace PicoContainer is gereserveerd voor de interne onderdelen van het IoC-pattern. Configuratie is opzettelijk buiten dit component gehouden. De PicoContainer is uitermate uitbreidbaar waardoor een eenduidige wijze van configuratie moeilijk te realiseren is.

Configuratie is beschikbaar in een ander component genaamd de NanoContainer. Met deze container kan de PicoContainer worden geconfigureerd met behulp van scripts. De huidige implementatie ondersteunt de meest gangbare programmeertalen voor .NET. Een script is een stuk code dat niet wordt gecompileerd, door de container wordt geïnterpreteerd en dat wordt gebruikt voor het configureren van de componenten.

De code uit de vorige sectie kan in een script worden gestopt en door de applicatie worden geladen. Indien een andere ImageManager moet worden gebruikt, hoeft slechts het script te worden aangepast (de applicatiecode blijft ongewijzigd) om de applicatie met de nieuwe implementatie te laten werken. Als de PicoContainer op deze wijze wordt ingezet, is het mogelijk een enkele applicatie te configureren met een enkele code base en verschillende services zonder de applicatie opnieuw te moeten compileren.

Voorbeelden van het gebruik van de PicoContainer bij Delta-N

Bij Delta-N wordt een aangepaste versie van UIProcess application block gebruikt waarbij de PicoContainer wordt ingezet. In deze aangepaste versie worden controllers en services geregistreerd in de PicoContainer. De controllers worden bij het aanmaken gevuld met de vereiste services waardoor de code flexibel en decoupled blijft.

De PicoContainer wordt tevens gebruikt om de afhankelijkheden van de services op te lossen door alle afhankelijke componenten tevens in de PicoContainer te registreren.

Tijdens het ontwerp vervangt een developer die bezig is met een onderdeel van het systeem alle afhankelijkheden waarvoor hij/zij niet verantwoordelijk is met stubs. Deze werkmethode maakt zijn/haar werk onafhankelijk van de onderdelen van het systeem die door anderen worden ontwikkeld.

In de integratiefase worden alle stubs, die zijn gedefinieerd in de PicoContainer, vervangen door de echte implementaties. Dit vindt plaats zonder ook maar iets aan de code te hoeven wijzigen.

PicoContainer broncode

Klik hier om de PicoContainer broncode te downloaden.

Microsoft

Delta-N

Delta-N B.V.

Laan van Waalhaven 287
2497 GL Den Haag

T: 070 - 357 57 00
F: 070 - 357 57 07
E: info@delta-n.nl