PLCnext API Documentation 24.0.0.71
ServiceManager.hpp
1
2//
3// Copyright PHOENIX CONTACT Electronics GmbH
4//
6#pragma once
8#include "Arp/System/Rsc/Services/Rsc.h"
9#include "Arp/System/Rsc/Services/IRscService.hpp"
10#include "Arp/System/Rsc/Services/IRscServiceProxy.hpp"
11#include "Arp/System/Rsc/Services/IRscServiceFactory.hpp"
12#include "Arp/System/Rsc/Services/IRscServiceProxyFactory.hpp"
13
14// forwards
15namespace CommonRemoting
16{
17class IService;
18class IServiceFactory;
19class IServiceProxyFactory;
20class CRemotingServiceProviderBase;
21}
22
23namespace Arp { namespace System { namespace Rsc
24{
25
26using namespace CommonRemoting;
27using namespace Arp::System::Rsc::Services;
28
32{
33private: // deleted construction/destruction
35 ServiceManager(void) = delete;
37 ServiceManager(const ServiceManager& arg) = delete;
39 ServiceManager& operator=(const ServiceManager& arg) = delete;
41 ~ServiceManager(void) = delete;
42
43public: // static Rsc service operations
48 template<class TService, class TServiceFactory>
49 static void PublishService(void);
50
55 template<class TService, class TServiceFactory>
56 static void PublishService(const char* serviceProviderName);
57
62 template<class TService>
63 static typename TService::Ptr GetService(void);
64
71 template<class TService>
72 static typename TService::Ptr GetService(const char* serviceProviderName);
73
78 template<class TService>
79 static bool TryGetService(typename TService::Ptr& result);
80
86 template<class TService>
87 static bool TryGetService(const char* serviceProviderName, typename TService::Ptr& result);
88
89public: // static Remoting service operations
94 static void PublishComponentService(const char* componentName, const char* serviceName, IRscServiceFactory* pServiceFactory);
95
99 static void PublishRemotingServiceProvider(CRemotingServiceProviderBase* pServiceProvider);
100
106 template<class TService, class TServiceFactory>
107 static void PublishRemotingService(const char* serviceProviderName);
108
114 template<class TService>
115 static typename TService::Ptr GetRemotingService(const char* serviceProviderName);
116
117private: // Rsc service methods
118 static void PublishService(const char* serviceProviderName, const char* serviceName, IRscServiceFactory& serviceFactory);
119 static void PublishService(const char* serviceProviderName, const char* serviceName, IServiceFactory& serviceFactory);
120 static IRscService* GetService(const char* serviceProviderName, IRscServiceProxyFactory& proxyFactory);
121 static IService* GetService(const char* serviceProviderName, IServiceProxyFactory& proxyFactory);
122};
123
125// inline methods of class ServiceManager
126
127template<class TService, class TServiceFactory>
129{
130 String serviceProviderName = TServiceFactory::GetInstance().GetServiceProviderName();
131 ServiceManager::PublishService(serviceProviderName, TService::GetProxyFactory().GetServiceName(), TServiceFactory::GetInstance());
132}
133
134template<class TService, class TServiceFactory>
135inline void ServiceManager::PublishService(const char* serviceProviderName)
136{
137 ServiceManager::PublishService(serviceProviderName, TService::GetProxyFactory().GetServiceName(), TServiceFactory::GetInstance());
138}
139
140template<class TService, class TServiceFactory>
141inline void ServiceManager::PublishRemotingService(const char* serviceProviderName)
142{
143 ServiceManager::PublishService(serviceProviderName, TService::GetProxyFactory().GetServiceName(), TServiceFactory::GetInstance());
144}
145
146template<class TService>
147inline typename TService::Ptr ServiceManager::GetService()
148{
149 String serviceProviderName = TService::GetProxyFactory().GetServiceProviderName();
150 if (serviceProviderName.IsEmpty())
151 {
152 throw ArgumentException::Create("TService", TService::GetProxyFactory().GetServiceName(), "Service does not specify a service provider");
153 }
154 typename TService::Ptr result;
155 if (!ServiceManager::TryGetService<TService>(serviceProviderName, result))
156 {
157 throw InvalidOperationException("Could not retrieve service '{0}' from service provider '{1}'.", TypeName<TService>(), serviceProviderName);
158 }
159 return result;
160}
161
162template<class TService>
163inline typename TService::Ptr ServiceManager::GetService(const char* serviceProviderName)
164{
165 typename TService::Ptr result;
166 if (!ServiceManager::TryGetService<TService>(serviceProviderName, result))
167 {
168 throw InvalidOperationException("Could not retrieve service '{0}' from service provider '{1}'.", TypeName<TService>(), serviceProviderName);
169 }
170 return result;
171}
172
173template<class TService>
174inline bool ServiceManager::TryGetService(typename TService::Ptr& result)
175{
176 const String& serviceProviderName = TService::GetProxyFactory().GetServiceProviderName();
177 if (serviceProviderName.IsEmpty())
178 {
179 throw ArgumentException::Create("TService", TService::GetProxyFactory().GetServiceName(), "Service does not specify a service provider");
180 }
181 // else
182 return ServiceManager::TryGetService<TService>(serviceProviderName, result);
183}
184
185template<class TService>
186inline bool ServiceManager::TryGetService(const char* serviceProviderName, typename TService::Ptr& result)
187{
188 IRscService* pService = ServiceManager::GetService(serviceProviderName, TService::GetProxyFactory());
189
190 if (pService == nullptr)
191 {
192 return false; // not found
193 }
194 TService* pResult = dynamic_cast<TService*>(pService);
195 if (pResult == nullptr)
196 {
197 // error: wrong type
198 throw InvalidCastException("The service does not implement service interface '{0}'.", TService::GetProxyFactory().GetServiceName());
199 }
200 // else
201 result = typename TService::Ptr(pResult);
202 return true;
203}
204
205template<class TService>
206inline typename TService::Ptr ServiceManager::GetRemotingService(const char* serviceProviderName)
207{
208 IService* pService = ServiceManager::GetService(serviceProviderName, TService::GetProxyFactory());
209 if (pService == nullptr)
210 {
211 return typename TService::Ptr(); // not found
212 }
213 TService* pResult = dynamic_cast<TService*>(pService);
214 if (pResult == nullptr)
215 {
216 // error: wrong type
217 throw InvalidCastException("The service does not implement service interface '{0}'.", TService::GetProxyFactory().GetServiceName());
218 }
219 // else
220 return typename TService::Ptr(pResult);
221}
222
223}}} // end of namespace Arp::System::Rsc
static ArgumentException Create(const char *paramName, const T &paramValue)
Creates an ArgumentException instance using a default message text.
Definition: ArgumentException.hpp:112
This exception is used when an invalid cast occurs.
Definition: InvalidCastException.hpp:15
This exception is used when a method call is invalid for object's current state.
Definition: InvalidOperationException.hpp:15
Use this class to publish and retrieve Rsc and Remoting services.
Definition: ServiceManager.hpp:32
static TService::Ptr GetService(void)
Gets a Rsc service of the service provider Arp.
Definition: ServiceManager.hpp:147
static bool TryGetService(typename TService::Ptr &result)
Tries to get a service of the service provider Arp.
Definition: ServiceManager.hpp:174
static TService::Ptr GetRemotingService(const char *serviceProviderName)
Gets a Remoting service of the specified service provider.
Definition: ServiceManager.hpp:206
static void PublishComponentService(const char *componentName, const char *serviceName, IRscServiceFactory *pServiceFactory)
Publishes a service of the specified service or type of the specified component, which serves as serv...
static void PublishRemotingService(const char *serviceProviderName)
Publishes a remoting service of the specified service provider.
Definition: ServiceManager.hpp:141
static void PublishService(void)
Registers a Rsc service.
Definition: ServiceManager.hpp:128
static void PublishRemotingServiceProvider(CRemotingServiceProviderBase *pServiceProvider)
Publishes a remoting service provider and all of its services.
Base interface for all Rsc service interface.
Definition: IRscService.hpp:20
This (meta programming) class provides the C++ typename of the as template argument passed type.
Definition: TypeName.hxx:67
bool IsEmpty() const
Determines if this string is empty.
Definition: BasicString.hxx:1087
@ System
System components used by the System, Device, Plc or Io domains.
Namespace for classes and interfaces for the Remote Service Call implementation
Root namespace for the PLCnext API