Search code examples
inversion-of-controlfantom

What is the criteria to choose between IocService and RegistryBuilder in Fantom afIoc


The documentation of Alien Factory's IoC framework for Fantom says:

You can use IocService to start IoC as a Fantom service:

IocService([MyModule#]).start
...
reg     := ((IocService) Service.find(IocService#)).registry
service := reg.dependencyByType(MyService#)
...
Service.find(IocService#).uninstall

Or use RegistryBuilder to manage the Registry instance manually;

reg := RegistryBuilder().addModule(MyModule#).build.startup
...
service := reg.dependencyByType(MyService#)
...
reg.shutdown

But what is the criteria to decide the appropriate way of initialising the registry on a specific scenario?


Solution

  • The short answer - use RegistryBuilder.

    The long answer prompted me to update the documentation... it's ongoing, but here's the current revision:

    Building the Registry

    Use RegistryBuilder to manually manage an IoC Registry instance. You would typically do this when running tests.

    registry := RegistryBuilder().addModule(MyModule#).build().startup()
    ...
    service := registry.dependencyByType(MyService#)
    ...
    registry.shutdown()
    

    Ensure modules are added from other IoC libraries the code uses. Example, if using the IocEnv library then add IocEnvModule:

    registry := RegistryBuilder().addModule(MyModule#).addModule(IocEnvModule#).build().startup()
    

    It's standard that IoC library modules are named after the library, but with a Module suffix.

    The IocService

    If your code runs in an IoC container, such as BedSheet, then the container manages the Registry instance for you.

    If running unit tests then typically you would create your own Registry instance and hold it as a variable / field.

    An alternative is to create a Fantom Service to hold the registry. This is useful in situations where static access to the Registry, such as fwt applications where you have very little control over how your classes are created.

    IocService is a helper class that extends 'Service' and contains convenience methods for creating and accessing the registry.

    For example, to create and start a Fantom IoC Service:

    IocService([MyModule#]).start()
    

    Then from anywhere in your code, it may be accessed with:

    iocService := (IocService) Service.find(IocService#)
    ...
    myService  := iocService.serviceById(MyService#.qname)
    

    Uninstall IocService like any other:

    Service.find(IocService#).uninstall()