一、前言
注册服务的时候能够用服务工厂来注册;
访问服务getServeice
中的plugin
参数是执行ctkPluginContext::getService(const ctkServiceReference&)
的插件,从而工厂根据执行的不同插件名称返回不同的服务实现
服务工厂的作用
- 在服务中可以知道是哪个其它插件在使用它;
- 懒汉式使用服务,需要的时候才new;
- 厂其它插件使用服务工厂和使用无服务工的服务,没有任何区别,代码都一样;
- 可根据需要创建多种实现的服务,就是多种服务对应一个插件;
二、新建插件
插件结构
- HelloService.h:接口类
- HelloImpl.h:实现类
- HelloActivator.h:激活类
- ServiceFactory.h:服务工厂
工程文件:Hello.pro
QT += core
QT -= gui
TEMPLATE = lib
CONFIG += plugin
TARGET = Hello
DESTDIR = $$OUT_PWD/bin/plugins
include($$PWD/../CTK/CTK_dependency.pri)
HEADERS += \
HelloActivator.h \
HelloImpl.h \
HelloService.h \
ServiceFactory.h
RESOURCES += \
qresource.qrc
接口类:HelloService.h
#ifndef HELLOSERVICE_H
#define HELLOSERVICE_H
#include <QtPlugin>
class HelloService
{
public:
virtual ~HelloService() {}
virtual void sayHello() = 0;
};
#define HelloService_iid "org.commontk.service.demos.HelloService"
Q_DECLARE_INTERFACE(HelloService, HelloService_iid)
#endif // HELLOSERVICE_H
实现类:HelloImpl.h
#ifndef HELLOIMPL_H
#define HELLOIMPL_H
#include "HelloService.h"
#include <QObject>
#include <QtDebug>
// HelloWorld
//---------------------------------------------------------
class HelloWorldImpl : public QObject, public HelloService
{
Q_OBJECT
Q_INTERFACES(HelloService)
public:
void sayHello() Q_DECL_OVERRIDE {
qDebug() << "Hello,World!";
}
};
// HelloCTK
//---------------------------------------------------------
class HelloCTKImpl : public QObject, public HelloService
{
Q_OBJECT
Q_INTERFACES(HelloService)
public:
void sayHello() Q_DECL_OVERRIDE {
qDebug() << "Hello,CTK!";
}
};
#endif // HELLOIMPL_H
激活类:HelloActivator.h
#ifndef HELLOACTIVATOR_H
#define HELLOACTIVATOR_H
#include <ctkPluginActivator.h>
#include <ctkPluginContext.h>
#include "HelloService.h"
#include "ServiceFactory.h"
class HelloActivator : public QObject, public ctkPluginActivator
{
Q_OBJECT
Q_INTERFACES(ctkPluginActivator)
Q_PLUGIN_METADATA(IID "HELLO")
public:
// 注册服务工厂
void start(ctkPluginContext* context) {
ServiceFactory *factory = new ServiceFactory();
context->registerService<HelloService>(factory);
}
void stop(ctkPluginContext* context) {
Q_UNUSED(context)
}
};
#endif // HELLOACTIVATOR_H
服务工厂:ServiceFactory.h
#ifndef SERVICEFACTORY_H
#define SERVICEFACTORY_H
#include <ctkServiceFactory.h>
#include <ctkPluginConstants.h>
#include <ctkVersion.h>
#include "HelloImpl.h"
class ServiceFactory : public QObject, public ctkServiceFactory
{
Q_OBJECT
Q_INTERFACES(ctkServiceFactory)
public:
ServiceFactory() : m_counter(0) {}
// 创建服务对象
QObject* getService(QSharedPointer<ctkPlugin> plugin, ctkServiceRegistration registration) Q_DECL_OVERRIDE {
Q_UNUSED(registration)
qDebug() << "Create object of HelloService for: " << plugin->getSymbolicName();
m_counter++;
qDebug() << "Number of plugins using service: " << m_counter;
QHash<QString, QString> headers = plugin->getHeaders();
ctkVersion version = ctkVersion::parseVersion(headers.value(ctkPluginConstants::PLUGIN_VERSION));
QString name = headers.value(ctkPluginConstants::PLUGIN_NAME);
QObject* hello = getHello(version);
return hello;
}
// 释放服务对象
void ungetService(QSharedPointer<ctkPlugin> plugin, ctkServiceRegistration registration, QObject* service) Q_DECL_OVERRIDE {
Q_UNUSED(plugin)
Q_UNUSED(registration)
Q_UNUSED(service)
qDebug() << "Release object of HelloService for: " << plugin->getSymbolicName();
m_counter--;
qDebug() << "Number of plugins using service: " << m_counter;
}
private:
// 根据不同的版本,获取不同的服务
QObject* getHello(ctkVersion version) {
if (version.toString().contains("alpha")) {
return new HelloWorldImpl();
} else {
return new HelloCTKImpl();
}
}
private:
int m_counter; // 计数器
};
#endif // SERVICEFACTORY_H