/// <summary>
        /// Create sdk factory
        /// </summary>
        /// <param name="config"></param>
        /// <param name="broker"></param>
        /// <param name="logger"></param>
        public IoTSdkFactory(IModuleConfig config, IEventSourceBroker broker, ILogger logger)
        {
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));

            if (broker != null)
            {
                _logHook = broker.Subscribe(IoTSdkLogger.EventSource, new IoTSdkLogger(logger));
            }

            // The runtime injects this as an environment variable
            var deviceId = Environment.GetEnvironmentVariable("IOTEDGE_DEVICEID");
            var moduleId = Environment.GetEnvironmentVariable("IOTEDGE_MODULEID");
            var ehubHost = Environment.GetEnvironmentVariable("IOTEDGE_GATEWAYHOSTNAME");

            try {
                if (!string.IsNullOrEmpty(config.EdgeHubConnectionString))
                {
                    _cs = IotHubConnectionStringBuilder.Create(config.EdgeHubConnectionString);

                    if (string.IsNullOrEmpty(_cs.SharedAccessKey))
                    {
                        throw new InvalidConfigurationException(
                                  "Connection string is missing shared access key.");
                    }
                    if (string.IsNullOrEmpty(_cs.DeviceId))
                    {
                        throw new InvalidConfigurationException(
                                  "Connection string is missing device id.");
                    }

                    deviceId = _cs.DeviceId;
                    moduleId = _cs.ModuleId;
                    ehubHost = _cs.GatewayHostName ?? ehubHost;

                    if (string.IsNullOrWhiteSpace(_cs.GatewayHostName) && !string.IsNullOrWhiteSpace(ehubHost))
                    {
                        _cs = IotHubConnectionStringBuilder.Create(
                            config.EdgeHubConnectionString + ";GatewayHostName=" + ehubHost);
                    }
                }
            }
            catch (Exception e) {
                _logger.Error(e, "Bad configuration value in EdgeHubConnectionString config.");
            }

            ModuleId = moduleId;
            DeviceId = deviceId;
            Gateway  = ehubHost;

            if (string.IsNullOrEmpty(DeviceId))
            {
                var ex = new InvalidConfigurationException(
                    "If you are running outside of an IoT Edge context or in EdgeHubDev mode, then the " +
                    "host configuration is incomplete and missing the EdgeHubConnectionString setting." +
                    "You can run the module using the command line interface or in IoT Edge context, or " +
                    "manually set the 'EdgeHubConnectionString' environment variable.");

                _logger.Error(ex, "The Twin module was not configured correctly.");
                throw ex;
            }

            _bypassCertValidation = config.BypassCertVerification;
            if (!_bypassCertValidation)
            {
                var certPath = Environment.GetEnvironmentVariable("EdgeModuleCACertificateFile");
                if (!string.IsNullOrWhiteSpace(certPath))
                {
                    InstallCert(certPath);
                }
                else if (!string.IsNullOrEmpty(ehubHost))
                {
                    _bypassCertValidation = true;
                }
            }
            if (!string.IsNullOrEmpty(ehubHost))
            {
                // Running in edge mode
                // the configured transport (if provided) will be forced to it's OverTcp
                // variant as follows: AmqpOverTcp when Amqp, AmqpOverWebsocket or AmqpOverTcp specified
                // and MqttOverTcp otherwise. Default is MqttOverTcp
                if ((config.Transport & TransportOption.Mqtt) != 0)
                {
                    // prefer Mqtt over Amqp due to performance reasons
                    _transport = TransportOption.MqttOverTcp;
                }
                else
                {
                    _transport = TransportOption.AmqpOverTcp;
                }
                _logger.Information("Connecting all clients to {edgeHub} using {transport}.",
                                    ehubHost, _transport);
            }
            else
            {
                _transport = config.Transport;
            }
            _timeout = TimeSpan.FromMinutes(5);
        }
        /// <summary>
        /// Create sdk factory
        /// </summary>
        /// <param name="config"></param>
        /// <param name="broker"></param>
        /// <param name="logger"></param>
        public IoTSdkFactory(IModuleConfig config, IEventSourceBroker broker, ILogger logger)
        {
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));

            if (broker != null)
            {
                _logHook = broker.Subscribe(IoTSdkLogger.EventSource, new IoTSdkLogger(logger));
            }

            // The runtime injects this as an environment variable
            var deviceId = Environment.GetEnvironmentVariable("IOTEDGE_DEVICEID");
            var moduleId = Environment.GetEnvironmentVariable("IOTEDGE_MODULEID");
            var ehubHost = Environment.GetEnvironmentVariable("IOTEDGE_GATEWAYHOSTNAME");

            try {
                if (!string.IsNullOrEmpty(config.EdgeHubConnectionString))
                {
                    _cs = IotHubConnectionStringBuilder.Create(config.EdgeHubConnectionString);

                    if (string.IsNullOrEmpty(_cs.SharedAccessKey))
                    {
                        throw new InvalidConfigurationException(
                                  "Connection string is missing shared access key.");
                    }
                    if (string.IsNullOrEmpty(_cs.DeviceId))
                    {
                        throw new InvalidConfigurationException(
                                  "Connection string is missing device id.");
                    }

                    deviceId = _cs.DeviceId;
                    moduleId = _cs.ModuleId;
                    ehubHost = _cs.GatewayHostName;
                }
            }
            catch (Exception e) {
                _logger.Error(e, "Bad configuration value in EdgeHubConnectionString config.");
            }

            ModuleId = moduleId;
            DeviceId = deviceId;

            if (string.IsNullOrEmpty(DeviceId))
            {
                var ex = new InvalidConfigurationException(
                    "If you are running outside of an IoT Edge context or in EdgeHubDev mode, then the " +
                    "host configuration is incomplete and missing the EdgeHubConnectionString setting." +
                    "You can run the module using the command line interface or in IoT Edge context, or " +
                    "manually set the 'EdgeHubConnectionString' environment variable.");

                _logger.Error(ex, "The Twin module was not configured correctly.");
                throw ex;
            }

            _bypassCertValidation = config.BypassCertVerification;
            if (!_bypassCertValidation)
            {
                var certPath = Environment.GetEnvironmentVariable("EdgeModuleCACertificateFile");
                if (!string.IsNullOrWhiteSpace(certPath))
                {
                    InstallCert(certPath);
                }
            }

            if (_bypassCertValidation)
            {
                // Running in debug mode - can only use mqtt over tcp
                _transport = TransportOption.MqttOverTcp;
            }
            else
            {
                _transport = config.Transport;
            }
            _timeout = TimeSpan.FromMinutes(5);
        }