How to find a girl or dependency injection pattern in action. Part II

vpereverzev

Vasily Pereverzev

Posted on January 7, 2020

How to find a girl or dependency injection pattern in action. Part II

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.

Alt Text

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 client

  • ServiceResolver - 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;
};
Enter fullscreen mode Exit fullscreen mode

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;                               \
    }                                            \
Enter fullscreen mode Exit fullscreen mode

Step 2

Register the DummyService, the implementation of the IDummyInterface.

ServicesResolver::registerService<IDummyInterface, DummyService>(
[]() -> DummyService* {
    return new DummyService();
});
Enter fullscreen mode Exit fullscreen mode

OR

// in case of singleton

ServicesResolver::registerService<IDummyInterface, DummyService>(
&DummyService::instance
);
Enter fullscreen mode Exit fullscreen mode

Step 3

Inherit our client from ServiceInjector:

#include "serviceinjector.h"

#include "interfaces/idummyinterface.h"

class DummyClient : public ServiceInjector<IDummyInterface>
{
...
};
Enter fullscreen mode Exit fullscreen mode

Inject dependency to the client:

#include "serviceinjector.h"

#include "interfaces/idummyinterface.h"

class DummyClient : public ServiceInjector<IDummyInterface>
{
    INJECT(IDummyInterface, dummyService)

    .....
};
Enter fullscreen mode Exit fullscreen mode

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);         \
    }                                                              \
Enter fullscreen mode Exit fullscreen mode

The full implementation details and code-snippets can be found at our open-source project:

GitHub logo 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!

MuseScore

Music notation and composition software

License: GPL v3

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

See Code Structure on Wiki

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…




💖 💪 🙅 🚩
vpereverzev
Vasily Pereverzev

Posted on January 7, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related