Implementation
In the previous part, we introduced the basic concepts of the dependency injection pattern.
Now it is time to make out an example implementation (in this example, I use the Qt / C ++ bundle). Let's imagine a basic simple case.
What can we see here?
Module A
Interface IDummyInterface
Service DummyService that implements interface IDummyInterface
Module B
ServiceInjector - the "dating agency".
Picks up metadata (contacts) of the necessary service from ServiceResolver (agency database) and injects it in the clientServiceResolver - the database of our "dating agency". Able to register services and submit their metadata (contacts) for subsequent injection
Module C
- DummyClient - client that needs the functionality declared in IDummyInterface. At the same time, he doesn't want to know anything about the details of the implementation of DummyService
Step 1
Add to the IDummyInterface interface the ability to represent ourselves through the unique identifier QUuid.
#include <servicesresolver.h>
class IDummyInterface
{
public:
INTERFACE_ID
virtual void doSomething() = 0;
};
The implementation of the macro is extremely simple - just creating a unique identifier.
#define INTERFACE_ID \
public: \
static const QUuid interfaceId() { \
static QUuid id = QUuid::createUuid(); \
return id; \
} \
Step 2
Register the DummyService, the implementation of the IDummyInterface.
ServicesResolver::registerService<IDummyInterface, DummyService>(
[]() -> DummyService* {
return new DummyService();
});
OR
// in case of singleton
ServicesResolver::registerService<IDummyInterface, DummyService>(
&DummyService::instance
);
Step 3
Inherit our client from ServiceInjector:
#include "serviceinjector.h"
#include "interfaces/idummyinterface.h"
class DummyClient : public ServiceInjector<IDummyInterface>
{
...
};
Inject dependency to the client:
#include "serviceinjector.h"
#include "interfaces/idummyinterface.h"
class DummyClient : public ServiceInjector<IDummyInterface>
{
INJECT(IDummyInterface, dummyService)
.....
};
The INJECT macro implementation is a simple setter and getter.
The first parameter is the type of interface.
The second parameter - an alias for the service in the scope of the client, needed for simplify calls of a service.
#define INJECT(INTERFACE_NAME, ALIAS) \
public: \
INTERFACE_NAME* ALIAS() { \
return ServiceInjector<INTERFACE_NAME>::getService(); \
} \
\
void set##ALIAS(INTERFACE_NAME* impl) { \
ServiceInjector<INTERFACE_NAME>::setService(impl); \
} \
The full implementation details and code-snippets can be found at our open-source project:
musescore / MuseScore
MuseScore is an open source and free music notation software. For support, contribution, bug reports, visit MuseScore.org. Fork and make pull requests!
Music notation and composition software
MuseScore is an open source and free music notation software. For support, contribution, and bug reports visit MuseScore.org. Fork and make pull requests!
Features
- WYSIWYG design, notes are entered on a "virtual notepaper"
- TrueType font(s) for printing & display allows for high quality scaling to all sizes
- Easy & fast note entry
- Many editing functions
- MusicXML import/export
- MIDI (SMF) import/export
- MEI import/export
- MuseData import
- MIDI input for note entry
- Integrated sequencer and software synthesizer to play the score
- Print or create PDF files
More info
License
MuseScore is licensed under GPL version 3.0. See license file in the same directory.
Packages
Building
Read the Compilation section of the MuseScore Wiki for a complete build walkthrough and a list of dependencies.
Getting sources
If using git to download repo of entire…
Top comments (3)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.