loading...
Cover image for How to find a girl or dependency injection pattern in action. Part II

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

vpereverzev profile image Vasily Pereverzev ・2 min read

How to find a girl or dependency injection pattern in action (2 Part Series)

1) How to find a girl or dependency injection pattern in action. Part I 2) 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;
};

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:

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

Travis CI Appveyor License: GPL v2

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
  • 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 2.0. See LICENSE.GPL in the same directory.

Packages

How to find a girl or dependency injection pattern in action (2 Part Series)

1) How to find a girl or dependency injection pattern in action. Part I 2) How to find a girl or dependency injection pattern in action. Part II

Posted on by:

vpereverzev profile

Vasily Pereverzev

@vpereverzev

Senior C++ developer. Currently working on open-source project MuseScore - https://github.com/musescore/MuseScore

Discussion

markdown guide
 

Interesting approach, i think i'll grab ur idea to my project. Thx!

 

Thank you for the article! I'm looking for QT-example for so long. 😍

 

BTW, is it possible to start contribute your project if i'm not so experienced in C++?

I would like to adopt your experience if it possible...