How do I implement dependancy injection in C++ explicitly without using frameworks or reflection?
I could use a factory to return a auto_ptr or a shared_ptr. Is this a good way to do it?
How do I implement dependancy injection in C++ explicitly without using frameworks or reflection?
I could use a factory to return a auto_ptr or a shared_ptr. Is this a good way to do it?
AFAIK dependency injection just means, that there is an interface to an component needed by another one.
namespace ifc {
struct service {
virtual ~service() {}
virtual do_stuff(/*..*/) = 0;
};
} // ns ifc
class ServiceProviderA : public ifc::service
{
public;
do_stuff(/*..*/) { /*...*/ }
};
class ServiceProviderB : public ifc::service {/*...*/};
class Client
{
public;
client(ifc::service*);
private:
ifc::service* m_service;
};
I can only guess, but is your question how to manage the lifetime of the injected Object?
Just use a shared_ptr to the service you need, and make a setter to it. E.g.:
class Engine;
class Car {
public:
void setEngine(shared_ptr<Engine> p_engine) {
this->m_engine = p_engine;
}
int onAcceleratorPedalStep(int p_gas_pedal_pressure) {
this->m_engine->setFuelValveIntake(p_gas_pedal_pressure);
int torque = this->m_engine->getTorque();
int speed = ... //math to get the car speed from the engine torque
return speed;
}
protected:
shared_ptr<Engine> m_engine;
}
// (now must create an engine and use setEngine when constructing a Car on a factory)
Avoid using auto_ptr, because you can't share it through more than one object (it transfers ownership when assigning).
How about assuming the ownership of the injected object transfers to the dependent object. This will solve the lifetime problem for composition avoiding usage of smart pointers. But, for complex situations where ownership matters smart pointers will be the choice.
class Car {
public:
Car(IEngine *pEngine) {
m_pEngine = pEngine;
}
...
~Car()
{
delete m_engine;
}
protected:
IEngine *m_pEngine;
}
For the cases where dependet is sure to have less lifetime than the injected object, its better to pass injected object as a reference. This will clearly indicate that the injected object is not owned by the dependet object.