Esempio n. 1
0
        public RestServiceConfiguration RetrieveCardPaymentServiceConfiguration(IOrganizationService organizationService, string configurationPrefix)
        {
            if (string.IsNullOrWhiteSpace(configurationPrefix))
            {
                configurationPrefix = String.Empty;
            }

            // Read the settings
            IDictionary <string, string> configSettings = organizationService.GetConfigurationStringValues(
                $"{configurationPrefix}{CardPaymentServiceSecureConfigurationKeys.ApiKey}",
                $"{configurationPrefix}{CardPaymentServiceSecureConfigurationKeys.TargetUrl}",
                $"{configurationPrefix}{CardPaymentServiceSecureConfigurationKeys.TargetHost}",
                $"{configurationPrefix}{CardPaymentServiceSecureConfigurationKeys.SecurityProtocol}",
                $"{configurationPrefix}{CardPaymentServiceSecureConfigurationKeys.SecurityHeader}");

            // Parse the settings
            SecurityProtocolType protocolType;

            Enum.TryParse(
                configSettings[$"{configurationPrefix}{CardPaymentServiceSecureConfigurationKeys.SecurityProtocol}"],
                out protocolType);

            RestServiceConfiguration config = new RestServiceConfiguration
            {
                ApiKey           = configSettings[$"{configurationPrefix}{CardPaymentServiceSecureConfigurationKeys.ApiKey}"],
                SecurityHeader   = configSettings[$"{configurationPrefix}{CardPaymentServiceSecureConfigurationKeys.SecurityHeader}"],
                SecurityProtocol = protocolType,
                TargetHost       = configSettings[$"{configurationPrefix}{CardPaymentServiceSecureConfigurationKeys.TargetHost}"],
                TargetUrl        = configSettings[$"{configurationPrefix}{CardPaymentServiceSecureConfigurationKeys.TargetUrl}"]
            };

            return(config);
        }
        /// <summary>
        /// Configure the setting
        /// </summary>
        /// <param name="configuration"></param>
        /// <param name="settings"></param>
        public void Configure(SanteDBConfiguration configuration, IDictionary <string, string> settings)
        {
            var metadataConf = configuration.GetSection <MetadataConfigurationSection>();

            if (metadataConf == null)
            {
                metadataConf = new MetadataConfigurationSection();
                configuration.AddSection(metadataConf);
            }

            var restConfiguration = configuration.GetSection <SanteDB.Rest.Common.Configuration.RestConfigurationSection>();

            if (restConfiguration == null)
            {
                throw new ConfigurationException("Error retrieving REST configuration", configuration);
            }

            var openApiRestConfiguration = restConfiguration.Services.FirstOrDefault(o => o.ServiceType == typeof(IMetadataServiceContract));

            if (openApiRestConfiguration == null) // add fhir rest config
            {
                openApiRestConfiguration = new RestServiceConfiguration()
                {
                    Name      = "META",
                    Endpoints = new List <RestEndpointConfiguration>()
                    {
                        new RestEndpointConfiguration()
                        {
                            Address     = "http://0.0.0.0:8080/api-docs",
                            ContractXml = typeof(IMetadataServiceContract).AssemblyQualifiedName,
                        }
                    }
                };
                restConfiguration.Services.Add(openApiRestConfiguration);
            }

            if (settings.TryGetValue(ListenSetting, out string listenStr))
            {
                if (!Uri.TryCreate(listenStr, UriKind.Absolute, out Uri listenUri))
                {
                    throw new ArgumentException($"{listenStr} is not a valid URI");
                }
                openApiRestConfiguration.Endpoints.ForEach(ep => ep.Address = listenStr);
            }

            // Client claims?
            if (settings.TryGetValue(ApiBaseSetting, out String baseSetting))
            {
                restConfiguration.ExternalHostPort = baseSetting;
            }

            // Add services
            var serviceConfiguration = configuration.GetSection <ApplicationServiceContextConfigurationSection>().ServiceProviders;

            if (!serviceConfiguration.Any(s => s.Type == typeof(MetadataMessageHandler)))
            {
                serviceConfiguration.Add(new TypeReferenceConfiguration(typeof(MetadataMessageHandler)));
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Query for the state of this rest service
        /// </summary>
        public FeatureInstallState QueryState(SanteDBConfiguration configuration)
        {
            // First, is the REST service enabled?
            if (!configuration.SectionTypes.Any(o => o.Type == typeof(RestConfigurationSection)))
            {
                configuration.AddSection(new RestConfigurationSection());
            }

            // Does the contract exist?
            var restConfiguration = configuration.GetSection <RestConfigurationSection>().Services.FirstOrDefault(s => s.Endpoints.Any(e => e.Contract == this.m_contractType));

            // Create / add section type
            if (!configuration.SectionTypes.Any(t => t.Type == this.m_configurationType))
            {
                configuration.SectionTypes.Add(new TypeReferenceConfiguration(this.m_configurationType));
            }

            // Does the section exist?
            var serviceConfiguration = configuration.GetSection(this.m_configurationType);

            // Feature state
            var featureState = serviceConfiguration != null && restConfiguration != null ? FeatureInstallState.Installed :
                               serviceConfiguration != null ^ restConfiguration != null ? FeatureInstallState.PartiallyInstalled :
                               FeatureInstallState.NotInstalled;

            // Do either exist?
            if (restConfiguration == null)
            {
                using (var s = this.m_configurationType.Assembly.GetManifestResourceStream(this.m_configurationType.Namespace + ".Default.xml"))
                    restConfiguration = RestServiceConfiguration.Load(s);
            }
            if (serviceConfiguration == null)
            {
                serviceConfiguration = Activator.CreateInstance(this.m_configurationType);
            }

            // Construct the configuraiton
            this.Configuration = new GenericFeatureConfiguration()
            {
                Categories = new Dictionary <string, string[]>()
                {
                    { "Misc", new string[] { "REST API", "Service" } }
                },
                Options = new Dictionary <string, Func <object> >()
                {
                    { "REST API", () => ConfigurationOptionType.Object },
                    { "Service", () => ConfigurationOptionType.Object }
                },
                Values = new Dictionary <string, object>()
                {
                    { "REST API", restConfiguration },
                    { "Service", serviceConfiguration }
                }
            };

            return(featureState);
        }
        /// <summary>
        /// Executes the WorkFlow.
        /// </summary>
        /// <param name="crmWorkflowContext">The <see cref="WorkFlowActivityBase.LocalWorkflowContext"/> which contains the
        /// <param name="executionContext" > <see cref="CodeActivityContext"/>
        /// </param>
        /// <remarks>
        /// For improved performance, Microsoft Dynamics 365 caches WorkFlow instances.
        /// The WorkFlow's Execute method should be written to be stateless as the constructor
        /// is not called for every invocation of the WorkFlow. Also, multiple system threads
        /// could execute the WorkFlow at the same time. All per invocation state information
        /// is stored in the context. This means that you should not use global variables in WorkFlows.
        /// </remarks>
        public override void ExecuteCRMWorkFlowActivity(CodeActivityContext executionContext, LocalWorkflowContext crmWorkflowContext)
        {
            var tracingService = executionContext.GetExtension <ITracingService>();

            tracingService.Trace("CreatePayment starting...");

            try
            {
                // 1. Validation
                ValidateNotNull(crmWorkflowContext);

                // 2. Prepare API Request
                tracingService.Trace("Calling PrepareCardPaymentRequest...");
                CreatePaymentRequest apiRequest = this.PrepareCardPaymentRequest(executionContext);

                // 2. Retrieve Configuration
                tracingService.Trace("Calling RetrieveCardPaymentServiceConfiguration...");
                RestServiceConfiguration cardServiceConfiguration = this.RetrieveCardPaymentServiceConfiguration(executionContext, ConfigurationPrefix.Get(executionContext));

                // 3. Set-up the Api Service
                tracingService.Trace("Instantiating CardPaymentService...");
                CardPaymentService cardPaymentService = new CardPaymentService(cardServiceConfiguration);

                // 4. Call the API
                tracingService.Trace("Calling GovPay CreatePayment with amount='{0}', description='{1}', reference='{2}', returnUrl='{3}'", apiRequest.amount, apiRequest.description, apiRequest.reference, apiRequest.return_url);
                CreatePaymentResponse apiResponse = cardPaymentService.CreatePayment(apiRequest);

                // TODO Log request and Response

                // 5. Return the response
                if (apiResponse != null && apiResponse.error_message != null)
                {
                    tracingService.Trace("Error message: {0}", apiResponse.error_message);
                }
                tracingService.Trace("Calling PrepareOutputParameters...");
                this.PrepareOutputParameters(executionContext, apiResponse, tracingService);
            }
            catch (Exception ex)
            {
                // Todo: Log the Error
                tracingService.Trace("Exception: " + ex);
                throw ex;
            }
        }
        /// <summary>
        /// Executes the WorkFlow.
        /// </summary>
        /// <param name="crmWorkflowContext">The <see cref="WorkFlowActivityBase.LocalWorkflowContext"/> which contains the
        /// <param name="executionContext" > <see cref="CodeActivityContext"/>
        /// </param>
        /// <remarks>
        /// For improved performance, Microsoft Dynamics 365 caches WorkFlow instances.
        /// The WorkFlow's Execute method should be written to be stateless as the constructor
        /// is not called for every invocation of the WorkFlow. Also, multiple system threads
        /// could execute the WorkFlow at the same time. All per invocation state information
        /// is stored in the context. This means that you should not use global variables in WorkFlows.
        /// </remarks>
        public override void ExecuteCRMWorkFlowActivity(CodeActivityContext executionContext, LocalWorkflowContext crmWorkflowContext)
        {
            var tracingService = executionContext.GetExtension <ITracingService>();

            tracingService.Trace("FindPayment starting...");

            try
            {
                // 1. Validation
                ValidateNotNull(crmWorkflowContext);

                // 2. Prepare API Request
                tracingService.Trace("Calling PrepareFindPaymentRequest...");
                FindPaymentRequest apiRequest = this.PrepareFindPaymentRequest(executionContext, crmWorkflowContext, tracingService);

                // 3. Retrieve Configuration
                tracingService.Trace("Calling RetrieveCardPaymentServiceConfiguration...");
                RestServiceConfiguration cardServiceConfiguration = this.RetrieveCardPaymentServiceConfiguration(executionContext, ConfigurationPrefix.Get(executionContext));

                // 4. Set-up the Api Service
                tracingService.Trace("Instantiating CardPaymentService...");
                CardPaymentService cardPaymentService = new CardPaymentService(cardServiceConfiguration);

                // 5. Call the API
                tracingService.Trace("Calling GovPay FindPayment...");
                FindPaymentResponse apiResponse = cardPaymentService.FindPayment(apiRequest);

                // 6. Return the response
                tracingService.Trace("Calling PrepareOutputParameters...");
                this.PrepareOutputParameters(executionContext, apiResponse, tracingService);
            }
            catch (Exception ex)
            {
                // Todo: Log the Error
                tracingService.Trace("Exception: " + ex);
                throw ex;
            }
        }
Esempio n. 6
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "DavidMorales.WebHost v1"));

                app.UseDeveloperExceptionPage();

                app.UseCors(builder =>
                {
                    builder.AllowAnyOrigin()
                    .AllowAnyMethod()
                    .AllowAnyHeader();
                });
            }
            else
            {
                //app.UseExceptionHandler("/Error");
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "DavidMorales.WebHost v1"));
                app.UseDeveloperExceptionPage();

                app.UseCors(builder =>
                {
                    builder.AllowAnyOrigin()
                    .AllowAnyMethod()
                    .AllowAnyHeader();
                });
            }

            RestServiceConfiguration.Configure(app);
            DatabaseConfiguration.Configure(app);
            IdentityServiceConfiguration.Configure(app);
            AuthenticationConfiguration.Configure(app);
            AppAuthorizationConfiguration.Configure(app);
        }
Esempio n. 7
0
        protected RestServiceConfiguration RetrieveCardPaymentServiceConfiguration(CodeActivityContext executionContext, string configurationPrefix)
        {
            if (string.IsNullOrWhiteSpace(configurationPrefix))
            {
                configurationPrefix = String.Empty;
            }

            IOrganizationServiceFactory factory = (IOrganizationServiceFactory)executionContext.GetExtension <IOrganizationServiceFactory>();
            IOrganizationService        service = factory.CreateOrganizationService(null);

            // Read the settings
            IDictionary <string, string> configSettings = service.GetConfigurationStringValues(
                $"{configurationPrefix}{CardPaymentServiceSecureConfigurationKeys.ApiKey}",
                $"{configurationPrefix}{CardPaymentServiceSecureConfigurationKeys.TargetUrl}",
                $"{configurationPrefix}{CardPaymentServiceSecureConfigurationKeys.TargetHost}",
                $"{configurationPrefix}{CardPaymentServiceSecureConfigurationKeys.SecurityProtocol}",
                $"{configurationPrefix}{CardPaymentServiceSecureConfigurationKeys.SecurityHeader}");

            // Parse the settings
            SecurityProtocolType protocolType;

            Enum.TryParse(
                configSettings[$"{configurationPrefix}{CardPaymentServiceSecureConfigurationKeys.SecurityProtocol}"],
                out protocolType);

            RestServiceConfiguration config = new RestServiceConfiguration
            {
                ApiKey           = configSettings[$"{configurationPrefix}{CardPaymentServiceSecureConfigurationKeys.ApiKey}"],
                SecurityHeader   = configSettings[$"{configurationPrefix}{CardPaymentServiceSecureConfigurationKeys.SecurityHeader}"],
                SecurityProtocol = protocolType,
                TargetHost       = configSettings[$"{configurationPrefix}{CardPaymentServiceSecureConfigurationKeys.TargetHost}"],
                TargetUrl        = configSettings[$"{configurationPrefix}{CardPaymentServiceSecureConfigurationKeys.TargetUrl}"]
            };

            return(config);
        }
Esempio n. 8
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // Api Rest Configuration
            RestServiceConfiguration.ConfigureServices(services);

            // Database configuration
            DatabaseConfiguration.ConfigureServices(services, Configuration);

            // Identity service configuration
            IdentityServiceConfiguration.ConfigureServices(services, Configuration);

            // Authorization
            AppAuthorizationConfiguration.ConfigureAuthorization(services);

            // Authentication configuration
            AuthenticationConfiguration.ConfigureServices(services, Configuration);

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo {
                    Title = "DavidMorales.WebHost", Version = "v1"
                });
            });



            // Identity
            services.AddTransient <AppIdentity>();
            services.TryAddSingleton <IHttpContextAccessor, HttpContextAccessor>();

            // Log
            services.AddLogging();

            // Cors
            services.AddCors();
        }
Esempio n. 9
0
        /// <summary>
        /// Configure
        /// </summary>
        /// <param name="configuration"></param>
        /// <param name="settings"></param>
        public void Configure(SanteDBConfiguration configuration, IDictionary <string, string> settings)
        {
            var oauthConf = configuration.GetSection <OAuthConfigurationSection>();

            if (oauthConf == null)
            {
                oauthConf = DockerFeatureUtils.LoadConfigurationResource <OAuthConfigurationSection>("SanteDB.Authentication.OAuth2.Docker.OauthFeature.xml");
                configuration.AddSection(oauthConf);
            }

            var restConfiguration = configuration.GetSection <SanteDB.Rest.Common.Configuration.RestConfigurationSection>();

            if (restConfiguration == null)
            {
                throw new ConfigurationException("Error retrieving REST configuration", configuration);
            }

            var oauthRestConfiguration = restConfiguration.Services.FirstOrDefault(o => o.ServiceType == typeof(IOAuthTokenContract));

            if (oauthRestConfiguration == null) // add fhir rest config
            {
                oauthRestConfiguration = new RestServiceConfiguration()
                {
                    Name      = "OAuth2",
                    Endpoints = new List <RestEndpointConfiguration>()
                    {
                        new RestEndpointConfiguration()
                        {
                            Address     = "http://0.0.0.0:8080/auth",
                            ContractXml = typeof(IOAuthTokenContract).AssemblyQualifiedName,
                        }
                    }
                };
                restConfiguration.Services.Add(oauthRestConfiguration);
            }

            if (settings.TryGetValue(ListenSetting, out string listenStr))
            {
                if (!Uri.TryCreate(listenStr, UriKind.Absolute, out Uri listenUri))
                {
                    throw new ArgumentException($"{listenStr} is not a valid URI");
                }
                oauthRestConfiguration.Endpoints.ForEach(ep => ep.Address = listenStr);
            }

            // Client claims?
            if (settings.TryGetValue(ClientClaimSetting, out String claim))
            {
                oauthConf.AllowedClientClaims = claim.Split(';').ToList();
            }

            // Token type?
            if (settings.TryGetValue(TokenTypeSetting, out String tokenType))
            {
                oauthConf.TokenType = tokenType;
            }

            // Allow insecure authentication?
            if (settings.TryGetValue(NodelessClientAuthSetting, out string insecureSetting))
            {
                if (!bool.TryParse(insecureSetting, out bool insecureBool))
                {
                    throw new ArgumentOutOfRangeException($"{insecureSetting} is not a valid boolean value");
                }
                oauthConf.AllowClientOnlyGrant = insecureBool;
            }

            // Issuer (used for client claims auth and oauth)
            if (settings.TryGetValue(IssuerIdSetting, out String issuer))
            {
                oauthConf.IssuerName = issuer;
            }

            if (settings.TryGetValue(JwtSigningKey, out String jwtSinging))
            {
                oauthConf.JwtSigningKey = jwtSinging;
            }

            // Add services
            var serviceConfiguration = configuration.GetSection <ApplicationServiceContextConfigurationSection>().ServiceProviders;

            if (!serviceConfiguration.Any(s => s.Type == typeof(OAuthMessageHandler)))
            {
                serviceConfiguration.Add(new TypeReferenceConfiguration(typeof(OAuthMessageHandler)));
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Configure the service
        /// </summary>
        public void Configure(SanteDBConfiguration configuration, IDictionary <string, string> settings)
        {
            var restConfiguration = configuration.GetSection <SanteDB.Rest.Common.Configuration.RestConfigurationSection>();

            if (restConfiguration == null)
            {
                throw new ConfigurationException("Error retrieving REST configuration", configuration);
            }

            var fhirRestConfiguration = restConfiguration.Services.FirstOrDefault(o => o.ServiceType == typeof(IFhirServiceContract));

            if (fhirRestConfiguration == null) // add fhir rest config
            {
                fhirRestConfiguration = new RestServiceConfiguration()
                {
                    Behaviors = new List <RestServiceBehaviorConfiguration>()
                    {
                        new RestServiceBehaviorConfiguration(typeof(TokenAuthorizationAccessBehavior))
                    },
                    Name      = "FHIR",
                    Endpoints = new List <RestEndpointConfiguration>()
                    {
                        this.CreateEndpoint("http://0.0.0.0:8080/fhir")
                    }
                };

                RestServiceConfiguration.Load(typeof(IFhirServiceContract).Assembly.GetManifestResourceStream("SanteDB.Messaging.FHIR.Configuration.Default.xml"));
                restConfiguration.Services.Add(fhirRestConfiguration);
            }

            var fhirConfiguration = configuration.GetSection <FhirServiceConfigurationSection>();

            if (fhirConfiguration == null)
            {
                fhirConfiguration = new FhirServiceConfigurationSection()
                {
                    ResourceBaseUri  = "http://127.0.0.1:8080/fhir",
                    ResourceHandlers = typeof(FhirDockerFeature).Assembly.ExportedTypes.Where(o => typeof(IFhirResourceHandler).IsAssignableFrom(o) && !o.IsAbstract && o.IsClass).Select(o => new TypeReferenceConfiguration(o)).ToList()
                };
                configuration.AddSection(fhirConfiguration);
            }

            // Listen address
            if (settings.TryGetValue(ListenUriSetting, out string listen))
            {
                if (!Uri.TryCreate(listen, UriKind.Absolute, out Uri listenUri))
                {
                    throw new ArgumentOutOfRangeException($"{listen} is not a valid URL");
                }

                // Setup the endpoint
                fhirRestConfiguration.Endpoints.Clear();
                fhirRestConfiguration.Endpoints.Add(new RestEndpointConfiguration()
                {
                    Address     = listen,
                    ContractXml = typeof(IFhirServiceContract).AssemblyQualifiedName,
                    Behaviors   = new List <RestEndpointBehaviorConfiguration>()
                    {
                        new RestEndpointBehaviorConfiguration(typeof(MessageLoggingEndpointBehavior)),
                        new RestEndpointBehaviorConfiguration(typeof(MessageCompressionEndpointBehavior)),
                        new RestEndpointBehaviorConfiguration(typeof(AcceptLanguageEndpointBehavior))
                    }
                });
            }

            // Authentication
            if (settings.TryGetValue(AuthenticationSetting, out string auth))
            {
                if (!this.authSettings.TryGetValue(auth.ToUpperInvariant(), out Type authType))
                {
                    throw new ArgumentOutOfRangeException($"Don't understand auth option {auth} allowed values {String.Join(",", this.authSettings.Keys)}");
                }

                // Add behavior
                if (authType != null)
                {
                    fhirRestConfiguration.Behaviors.Add(new RestServiceBehaviorConfiguration()
                    {
                        Type = authType
                    });
                }
                else
                {
                    fhirRestConfiguration.Behaviors.RemoveAll(o => this.authSettings.Values.Any(v => v == o.Type));
                }
            }

            // Has the user set CORS?
            if (settings.TryGetValue(CorsSetting, out string cors))
            {
                if (!Boolean.TryParse(cors, out bool enabled))
                {
                    throw new ArgumentOutOfRangeException($"{cors} is not a valid boolean value");
                }

                // Cors is disabled?
                if (!enabled)
                {
                    fhirRestConfiguration.Endpoints.ForEach(ep => ep.Behaviors.RemoveAll(o => o.Type == typeof(CorsEndpointBehavior)));
                }
                else
                {
                    fhirRestConfiguration.Endpoints.ForEach(ep => ep.Behaviors.RemoveAll(o => o.Type == typeof(CorsEndpointBehavior)));
                    fhirRestConfiguration.Endpoints.ForEach(ep => ep.Behaviors.Add(new RestEndpointBehaviorConfiguration()
                    {
                        Type = typeof(CorsEndpointBehavior)
                    }));
                }
            }

            // Base URI
            if (settings.TryGetValue(BaseUriSetting, out string baseUri))
            {
                fhirConfiguration.ResourceBaseUri = baseUri;
            }

            // Custom resource list?
            if (settings.TryGetValue(ResourceSetting, out string resource))
            {
                fhirConfiguration.Resources = new List <string>();
                foreach (var res in resource.Split(';'))
                {
                    if (!Enum.TryParse <Hl7.Fhir.Model.ResourceType>(res, out Hl7.Fhir.Model.ResourceType rt))
                    {
                        throw new ArgumentOutOfRangeException($"{res} is not a valid FHIR resource");
                    }

                    // Add resource setting
                    fhirConfiguration.Resources.Add(res);
                }
            }

            // Custom operation list?
            if (settings.TryGetValue(OperationSetting, out string operations))
            {
                fhirConfiguration.Operations = new List <string>();
                foreach (var res in operations.Split(';'))
                {
                    fhirConfiguration.Operations.Add(res);
                }
            }
            // Custom profile list?
            if (settings.TryGetValue(ProfileSetting, out string profiles))
            {
                fhirConfiguration.Profiles = new List <string>();
                foreach (var res in profiles.Split(';'))
                {
                    fhirConfiguration.Profiles.Add(res);
                }
            }
            // Custom settings
            if (settings.TryGetValue(ExtensionSetting, out string extensions))
            {
                fhirConfiguration.Extensions = new List <string>();
                foreach (var res in extensions.Split(';'))
                {
                    fhirConfiguration.Extensions.Add(res);
                }
            }
            // Custom message list?
            if (settings.TryGetValue(MessageSetting, out string messages))
            {
                fhirConfiguration.Messages = new List <string>();
                foreach (var res in messages.Split(';'))
                {
                    fhirConfiguration.Messages.Add(res);
                }
            }

            // Add services
            var serviceConfiguration = configuration.GetSection <ApplicationServiceContextConfigurationSection>().ServiceProviders;

            if (!serviceConfiguration.Any(s => s.Type == typeof(FhirMessageHandler)))
            {
                serviceConfiguration.Add(new TypeReferenceConfiguration(typeof(FhirMessageHandler)));
                serviceConfiguration.Add(new TypeReferenceConfiguration(typeof(FhirDataInitializationService)));
            }
        }
 public CardPaymentService(RestServiceConfiguration configuration)
     : base(configuration)
 {
 }