PLCnext API Documentation  22.9.0.33
ServiceManager.hpp
1 //
3 // Copyright PHOENIX CONTACT Electronics GmbH
4 //
6 #pragma once
7 #include "Arp/System/Core/Arp.h"
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
15 namespace CommonRemoting
16 {
17 class IService;
18 class IServiceFactory;
19 class IServiceProxyFactory;
20 class CRemotingServiceProviderBase;
21 }
22 
23 namespace Arp { namespace System { namespace Rsc
24 {
25 
26 using namespace CommonRemoting;
27 using namespace Arp::System::Rsc::Services;
28 
32 {
33 private: // 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 
43 public: // 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 
89 public: // 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 
117 private: // 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 
127 template<class TService, class TServiceFactory>
129 {
130  String serviceProviderName = TServiceFactory::GetInstance().GetServiceProviderName();
131  ServiceManager::PublishService(serviceProviderName, TService::GetProxyFactory().GetServiceName(), TServiceFactory::GetInstance());
132 }
133 
134 template<class TService, class TServiceFactory>
135 inline void ServiceManager::PublishService(const char* serviceProviderName)
136 {
137  ServiceManager::PublishService(serviceProviderName, TService::GetProxyFactory().GetServiceName(), TServiceFactory::GetInstance());
138 }
139 
140 template<class TService, class TServiceFactory>
141 inline void ServiceManager::PublishRemotingService(const char* serviceProviderName)
142 {
143  ServiceManager::PublishService(serviceProviderName, TService::GetProxyFactory().GetServiceName(), TServiceFactory::GetInstance());
144 }
145 
146 template<class TService>
147 inline 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>().Value, serviceProviderName);
158  }
159  return result;
160 }
161 
162 template<class TService>
163 inline 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>().Value, serviceProviderName);
169  }
170  return result;
171 }
172 
173 template<class TService>
174 inline 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 
185 template<class TService>
186 inline 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 
205 template<class TService>
206 inline 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:19
This (meta programming) class provides the C++ typename of the as template argument passed type.
Definition: TypeName.hxx:56
bool IsEmpty() const
Determines if this string is empty.
Definition: BasicString.hxx:1076
@ System
System components used by the System, Device, Plc or Io domains.
Namespace for classes and interfaces for the Remote Service Call implementation
Definition: IRscReadEnumerator.hxx:10
Root namespace for the PLCnext API