上下文:我有一个第三方记录器类,该类具有采用任意nr参数的可变参数函数。在我的代码库中,我有几个需要记录信息的类。我希望能够通过依赖关系注入来提供实例,而不是对第三方记录器类进行硬编码。这样,如果我想在运行时禁用日志记录,我还可以提供一个空对象。
示例代码:
//third partycode
class Logger{
public:
template<typename ...Ts>
void Log(const char * format, Ts... params);
};
//own code
class NullLogger{
public:
template<typename ...Ts>
void Log(const char * format, Ts... params); // doesn't do actual logging
};
class SomeClass{
public:
template<typename LOGGER>
void SetLogger(std::shared_ptr<LOGGER> logger){ m_logger = logger;}
void SomeFunction(){
m_logger->Log("test {0},{1}", 42, 13.37);
}
private:
??? m_logger;
};
问题:如何使以上代码起作用?
我的要求:
您将无法注入任何非可注入的依赖项。也许是logger,您将尝试查看如何实现Log功能。Log函数是模板,因此现在不能被覆盖:
//third partycode
class Logger{
public:
template<typename ...Ts>
void Log(const char * format, Ts... params);
};
您应该检查功能日志的实现方式
template<typename ...Ts>
void Log(const char * format, Ts... params)
{maybe it calls here any virtual_function(format, params...);}
如果它调用任何虚函数,您可以覆盖它:
//own code
class NullLogger: Logger{
public:
virtual_function(const char * format, Ts... params); // override
};
也许还有另一种方式,例如,您可以提供Logger使用的任何特定流对象。因此,如果您成功完成以上所有步骤,便可以注射,否则就别无选择:
class SomeClass{
public:
void SetLogger(std::shared_ptr<Logger> logger){ m_logger = logger;}
void SomeFunction(){
m_logger->Log("test {0},{1}", 42, 13.37);
}
private:
std::shared_ptr<Logger> m_logger;
};