PLCnext API Documentation  21.0.0.35466
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 
63  template<class TService>
64  static typename TService::Ptr GetService(void);
65 
72  template<class TService>
73  static typename TService::Ptr GetService(const char* serviceProviderName);
74 
79  template<class TService>
80  static bool TryGetService(typename TService::Ptr& result);
81 
87  template<class TService>
88  static bool TryGetService(const char* serviceProviderName, typename TService::Ptr& result);
89 
90 public: // static Remoting service operations
95  static void PublishComponentService(const char* componentName, const char* serviceName, IRscServiceFactory* pServiceFactory);
96 
100  static void PublishRemotingServiceProvider(CRemotingServiceProviderBase* pServiceProvider);
101 
107  template<class TService, class TServiceFactory>
108  static void PublishRemotingService(const char* serviceProviderName);
109 
115  template<class TService>
116  static typename TService::Ptr GetRemotingService(const char* serviceProviderName);
117 
118 private: // Rsc service methods
119  static void PublishService(const char* serviceProviderName, const char* serviceName, IRscServiceFactory& serviceFactory);
120  static void PublishService(const char* serviceProviderName, const char* serviceName, IServiceFactory& serviceFactory);
121  static IRscService* GetService(const char* serviceProviderName, IRscServiceProxyFactory& proxyFactory);
122  static IService* GetService(const char* serviceProviderName, IServiceProxyFactory& proxyFactory);
123 };
124 
126 // inline methods of class ServiceManager
127 
128 template<class TService, class TServiceFactory>
129 inline void ServiceManager::PublishService(void)
130 {
131  String serviceProviderName = TServiceFactory::GetInstance().GetServiceProviderName();
132  ServiceManager::PublishService(serviceProviderName, TService::GetProxyFactory().GetServiceName(), TServiceFactory::GetInstance());
133 }
134 
135 template<class TService, class TServiceFactory>
136 inline void ServiceManager::PublishService(const char* serviceProviderName)
137 {
138  if (serviceProviderName == nullptr || strlen(serviceProviderName) == 0)
139  {
140  throw ArgumentNullException::Create("serviceProviderName");
141  }
142  ServiceManager::PublishService(serviceProviderName, TService::GetProxyFactory().GetServiceName(), TServiceFactory::GetInstance());
143 }
144 
145 template<class TService, class TServiceFactory>
146 inline void ServiceManager::PublishRemotingService(const char* serviceProviderName)
147 {
148  if (serviceProviderName == nullptr || strlen(serviceProviderName) == 0)
149  {
150  throw ArgumentNullException::Create("serviceProviderName");
151  }
152  ServiceManager::PublishService(serviceProviderName, TService::GetProxyFactory().GetServiceName(), TServiceFactory::GetInstance());
153 }
154 
155 template<class TService>
156 inline typename TService::Ptr ServiceManager::GetService()
157 {
158  String serviceProviderName = TService::GetProxyFactory().GetServiceProviderName();
159  if (serviceProviderName.IsEmpty())
160  {
161  throw ArgumentException::Create("TService", TService::GetProxyFactory().GetServiceName(), "Service does not specify a service provider");
162  }
163  typename TService::Ptr result;
164  if (!ServiceManager::TryGetService<TService>(serviceProviderName, result))
165  {
166  throw InvalidOperationException("Could not retrieve service '{0}' from service provider '{1}'.", TypeName<TService>().Value, serviceProviderName);
167  }
168  return result;
169 }
170 
171 template<class TService>
172 inline typename TService::Ptr ServiceManager::GetService(const char* serviceProviderName)
173 {
174  if (serviceProviderName == nullptr || strlen(serviceProviderName) == 0)
175  {
176  throw ArgumentNullException::Create("serviceProviderName");
177  }
178  typename TService::Ptr result;
179  if (!ServiceManager::TryGetService<TService>(serviceProviderName, result))
180  {
181  throw InvalidOperationException("Could not retrieve service '{0}' from service provider '{1}'.", TypeName<TService>().Value, serviceProviderName);
182  }
183  return result;
184 }
185 
186 template<class TService>
187 inline bool ServiceManager::TryGetService(typename TService::Ptr& result)
188 {
189  const String& serviceProviderName = TService::GetProxyFactory().GetServiceProviderName();
190  if (serviceProviderName.IsEmpty())
191  {
192  throw ArgumentException::Create("TService", TService::GetProxyFactory().GetServiceName(), "Service does not specify a service provider");
193  }
194  // else
195  return ServiceManager::TryGetService<TService>(serviceProviderName, result);
196 }
197 
198 template<class TService>
199 inline bool ServiceManager::TryGetService(const char* serviceProviderName, typename TService::Ptr& result)
200 {
201  if (serviceProviderName == nullptr || strlen(serviceProviderName) == 0)
202  {
203  throw ArgumentNullException::Create("serviceProviderName");
204  }
205 
206  IRscService* pService = ServiceManager::GetService(serviceProviderName, TService::GetProxyFactory());
207 
208  if (pService == nullptr)
209  {
210  return false; // not found
211  }
212  TService* pResult = dynamic_cast<TService*>(pService);
213  if (pResult == nullptr)
214  {
215  // error: wrong type
216  throw InvalidCastException("The service does not implement service interface '{0}'.", TService::GetProxyFactory().GetServiceName());
217  }
218  // else
219  result = typename TService::Ptr(pResult);
220  return true;
221 }
222 
223 template<class TService>
224 inline typename TService::Ptr ServiceManager::GetRemotingService(const char* serviceProviderName)
225 {
226  if (serviceProviderName == nullptr || strlen(serviceProviderName) == 0)
227  {
228  throw ArgumentNullException::Create("serviceProviderName");
229  }
230  IService* pService = ServiceManager::GetService(serviceProviderName, TService::GetProxyFactory());
231  if (pService == nullptr)
232  {
233  return typename TService::Ptr(); // not found
234  }
235  TService* pResult = dynamic_cast<TService*>(pService);
236  if (pResult == nullptr)
237  {
238  // error: wrong type
239  throw InvalidCastException("The service does not implement service interface '{0}'.", TService::GetProxyFactory().GetServiceName());
240  }
241  // else
242  return typename TService::Ptr(pResult);
243 }
244 
245 }}} // end of namespace Arp::System::Rsc
This (meta programming) class provides the C++ typename of the as template argument passed type...
Definition: TypeName.hxx:55
Namespace for classes and interfaces for the Remote Service Call implementation
Definition: IRscReadEnumerator.hxx:9
This exception is used when an invalid cast occurs.
Definition: InvalidCastException.hpp:14
bool IsEmpty() const
Determines if this string is empty.
Definition: BasicString.hxx:1099
Definition: RemotingReader.hpp:10
This exception is used when a method call is invalid for object&#39;s current state.
Definition: InvalidOperationException.hpp:14
Use this class to publish and retrieve Rsc and Remoting services.
Definition: ServiceManager.hpp:31
Root namespace for the PLCnext API
Base interface for all Rsc service interface.
Definition: IRscService.hpp:18
System components used by the System, Device, Plc or Io domains.