2009-06-29 5 views
4

Как реализовать инъекцию зависимостей в C++ явно без использования фреймворков или отражений?Инъекция зависимостей в C++

Я могу использовать фабрику для возврата auto_ptr или shared_ptr. Это хороший способ сделать это?

+3

Мы не используем этот материал в C++. – 2009-06-29 21:33:54

+0

Хорошо, Нил! ^^ –

ответ

4

Просто используйте shared_ptr для службы, в которой вы нуждаетесь, и создайте для нее сеттер. Например .:

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) 

Избегайте использования auto_ptr, потому что вы не можете поделиться ею с помощью более чем одного объекта (он передает право собственности при назначении).

+0

Звучит очень разумно. Можно ли это сделать, чтобы сделать код пригодным для тестирования или есть лучшие альтернативы? – frast

+0

Все в порядке, вы не потеряете слишком большую производительность, и ваш код будет намного более гибким и проверким! –

1

Активация зависимостей AFAIK просто означает, что есть интерфейс к компоненту, который нужен другому.

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; 
}; 

Я могу только догадываться, но это ваш вопрос, как управлять временем жизни введенного объекта?

+0

Ваш код очень близок к проблеме. И да, вопрос в том, как управлять временем жизни инжектируемых объектов. – frast

0

Как насчет того, чтобы передача права на вложенный объект переносилась на зависимый объект. Это позволит решить проблему продолжительности жизни для композиции, избегая использования интеллектуальных указателей. Но для сложных ситуаций, когда владение имеет дело с интеллектуальными указателями, будет выбор.

class Car { 
    public: 
     Car(IEngine *pEngine) { 
     m_pEngine = pEngine; 
     } 

     ... 

     ~Car() 
     { 
     delete m_engine; 
     } 

    protected: 
     IEngine *m_pEngine; 
    } 

Для тех случаев, когда dependet обязательно иметь меньше, чем срок службы нагнетаемой объекта, его лучше передать впрыскивается объект в качестве ссылки. Это будет ясно указывать на то, что инжектируемый объект не принадлежит объекту-зависимой.

Смежные вопросы