The Bio-Formats service infrastructure is an interface driven pattern for dealing with external and internal dependencies. The design goal was mainly to avoid the cumbersome usage of ReflectedUniverse where possible and to clearly define both service dependency and interface between components. This is generally referred to as dependency injection, dependency inversion or component based design.
It was decided, at this point, to forgo the usage of potentially more powerful but also more complicated solutions such as:
The Wikipedia page for dependency injection contains many other implementations in many languages.
An added benefit is the potential code reuse possibilities as a result of decoupling of dependency and usage in Bio-Formats readers. Implementations of the initial Bio-Formats services were completed as part of BioFormatsCleanup and tickets #463 and #464.
Interface – The basic form of a service is an interface which inherits from loci.common.services.Service. Here is a very basic example using the (now removed) OMENotesService
public interface OMENotesService extends Service {
/**
* Creates a new OME Notes instance.
* @param filename Path to the file to create a Notes instance for.
*/
public void newNotes(String filename);
}
Implementation – This service then has an implementation, which is usually located in the Bio-Formats component or package which imports classes from an external, dynamic or other dependency. Again looking at the OMENotesService:
public class OMENotesServiceImpl extends AbstractService
implements OMENotesService {
/**
* Default constructor.
*/
public OMENotesServiceImpl() {
checkClassDependency(Notes.class);
}
/* (non-Javadoc)
* @see loci.formats.dependency.OMENotesService#newNotes()
*/
public void newNotes(String filename) {
new Notes(null, filename);
}
}
Style
Registration – A service’s interface and implementation must finally be registered with the loci.common.services.ServiceFactory via the services.properties file. Following the OMENotesService again, here is an example registration:
...
# OME notes service (implementation in legacy ome-notes component)
loci.common.services.OMENotesService=loci.ome.notes.services.OMENotesServiceImpl
...
OMENotesService service = null;
try {
ServiceFactory factory = new ServiceFactory();
service = factory.getInstance(OMENotesService.class);
}
catch (DependencyException de) {
LOGGER.info("", de);
}
...