ServiceRegistrationBase ServiceRegistry::RegisterService( BundlePrivate* bundle, const InterfaceMapConstPtr& service, const ServiceProperties& properties) { if (!service || service->empty()) { throw std::invalid_argument( "Can't register empty InterfaceMap as a service"); } // Check if we got a service factory bool isFactory = service->count("org.cppmicroservices.factory") > 0; bool isPrototypeFactory = (isFactory ? static_cast<bool>(std::dynamic_pointer_cast<PrototypeServiceFactory>( std::static_pointer_cast<ServiceFactory>( service->find("org.cppmicroservices.factory")->second))) : false); std::vector<std::string> classes; // Check if service implements claimed classes and that they exist. for (auto i : *service) { if (i.first.empty() || (!isFactory && i.second == nullptr)) { throw std::invalid_argument("Can't register as null class"); } classes.push_back(i.first); } ServiceRegistrationBase res( bundle, service, CreateServiceProperties( properties, classes, isFactory, isPrototypeFactory)); { auto l = this->Lock(); US_UNUSED(l); services.insert(std::make_pair(res, classes)); serviceRegistrations.push_back(res); for (auto& clazz : classes) { std::vector<ServiceRegistrationBase>& s = classServices[clazz]; std::vector<ServiceRegistrationBase>::iterator ip = std::lower_bound(s.begin(), s.end(), res); s.insert(ip, res); } } ServiceReferenceBase r = res.GetReference(std::string()); ServiceListeners::ServiceListenerEntries listeners; ServiceEvent registeredEvent(ServiceEvent::SERVICE_REGISTERED, r); bundle->coreCtx->listeners.GetMatchingServiceListeners(registeredEvent, listeners); bundle->coreCtx->listeners.ServiceChanged(listeners, registeredEvent); return res; }
ServiceRef::Ptr ServiceRegistry::registerService(const std::string& name, Service::Ptr pService, const Properties& props) { Poco::ScopedLockWithUnlock<FastMutex> lock(_mutex); ServiceMap::iterator it = _services.find(name); if (it == _services.end()) { ServiceRef::Ptr pServiceRef(new ServiceRef(name, props, pService)); pServiceRef->properties().set(PROP_NAME, name); pServiceRef->properties().set(PROP_TYPE, std::string(pService->type().name())); _services[name] = pServiceRef; lock.unlock(); ServiceEvent registeredEvent(pServiceRef, ServiceEvent::EV_SERVICE_REGISTERED); serviceRegistered(this, registeredEvent); _logger.information(std::string("Service registered: ") + name); return pServiceRef; } else throw Poco::ExistsException(name); }