Inversion of Control Container met interfaces header image

Inversion of Control Container met interfaces

maandag 29 juni 2020 ·Leestijd: 3 minuten
contacteer auteur:

In vorige blogitems schreef ik over interfaces en hoe ze ervoor zorgen dat je software beter te testen is en hoe ze helpen bij het uitbreiden van je software. Een andere voordeel van interfaces is dat ze je kunnen helpen bij het onderhouden van je software. Dat kan enerzijds door via het contract af te dwingen hoe een object, als implementatie van een bepaalde interface, dient te werken en anderzijds doordat je gedwongen wordt je implementaties te definiëren en het is logisch dat in sommige gevallen op een slimme plek te doen. IFileSystem is hier een goed voorbeeld: het zal niet voorkomen (of bij hoge uitzondering) dat je in je software meer dan één implementatie hiervan gebruikt. Tijdens het testen zal je weliswaar een specifieke implementatie gebruiken, maar je daadwerkelijke applicatie maakt gebruik van je lokale schijven óf van een Cloud-oplossing, maar niet van beide. Het is dus verstandig de initialisatie van deze implementatie in je software zo snel en globaal mogelijk te doen.

Bijvoorbeeld, ik zou al mijn implementaties kunnen initialiseren in een aparte functie die ik meteen aanroep:

    private static IFileSystem fileSystem;

    static void Main(string[] args)
    {
        InitClasses();

        // Doe hier dingen.

        storeReview(review, fileSystem);
    }

    private static void InitClasses()
    {
        fileSystem = new ActualFileSystem();
    }

Waarschijnlijk gebruik je hiervoor dan een aparte klasse, maar het idee is hetzelfde: je geeft op één plek aan welke implemenatie gebruikt wordt voor IFileSystem en andere interfaces. Wil je er één aanpassen of iets toevoegen, zoals een bepaalde configuratie, dan doe je dat in InitClasses.

In .NET (en andere programmeeromgevingen) kan je gebruikmaken van een Inversion of Control Container om zoveel mogelijk van deze logica voor je te regelen. Je geeft dan meestal alleen aan welke implementatie je wilt hebben voor welke interface en op veel plekken kan je deze implementatie gewoon ophalen via de container, terwijl je het maar op één plek hebt gedefinieerd. In .NET Core kan je hier bijvoorbeeld Unity Container voor gebruiken.

Eerst plaats ik de review-code in een aparte klasse:

static void Main(string[] args)
{
    InitClasses();

    var reviewApp = new ReviewApp(fileSystem);

    reviewApp.StoreReviews();
}

//...

public ReviewApp(IFileSystem fileSystem)
{
    this.fileSystem = fileSystem;
}

Als ik dit uitvoer, dan werkt het zoals het al deed. Om Unity Container te gebruiken moet ik enkele aanpassingen doen:

private static UnityContainer iocContainer;

static void Main(string[] args)
{
    InitClasses();

    var reviewApp = iocContainer.Resolve<ReviewApp>();

    reviewApp.StoreReviews();
}

private static void InitClasses()
{
    iocContainer = new UnityContainer();
    iocContainer.RegisterType<IFileSystem, ActualFileSystem>();
}

In bovenstaande voorbeeld laat ik iocContainer alles regelen. De container ziet dat ReviewApp een IFileSystem verwacht in de constructor en zoekt op welke ik heb ingesteld en geeft deze mee. Als ik nou een tweede argument verwacht (INetworkHandler bijvoorbeeld), dan hoef ik de initialisatie maar op 2 plekken aan te passen:

public ReviewApp(IFileSystem fileSystem, INetworkHandler networkHandler)
// ...
private static void InitClasses()
    //...
    iocContainer.RegisterType<IFileSystem, ActualFileSystem>();
    iocContainer.RegisterType<INetworkHandler, MyNetworkHandler>();

De container "weet" dat mijn constructor een INetworkHandler verwacht en zoekt op welke ik heb ingesteld. Door op zo min mogelijk plekken aanpassingen te doen, heb ik de software minder complex gemaakt en gemakkelijker te onderhouden. In bovenstaande voorbeeld voegt de IoC Container niet bepaald veel waarde toe. Er zijn echter meer voordelen en het zorgt er ook voor dat je gedwongen wordt je code logischer in elkaar te zetten. Zie voor meer informatie ook: http://unitycontainer.org/articles/introduction.html.


Andere blogartikelen

Integraties met API's van verschillende partijen
Geschreven door
op donderdag 30 juni 2022
Bij Sigma Solutions maken wij integraties met verschillende partijen, die ervoor zorgen dat jouw bedrijfsproces geautomatiseerd en gedigitaliseerd kan worden. We zijn constant op zoek naar passende oplossingen voor onze klanten.
Wat is B2B Online Advertising?
Geschreven door
op donderdag 30 juni 2022
B2B Online Advertising is een marketingstrategie die bedoeld is om een zakelijke boodschap over te brengen aan andere bedrijven door middel van advertenties.
Als traditioneel bedrijf succesvol blijven in een tijdperk van digitalisering
Geschreven door
op donderdag 30 juni 2022
Wil je als traditioneel bedrijf succesvol blijven in een tijdperk van 'digital natives'? Lees dan deze blogpost!
Open Nieuwsbrief Inschrijving Footer

E-book

Zo wordt uw website een lead generator 
In 3 stappen uw website van visitekaartje naar salesfunnel

Download het E-book â€º