public EnrichmentMessageRouter(IDataSource dataSource, IDataSink dataSink, IIoTDeviceDataEnricher dataEnricher, ITelemetryClient telemetryClient, IConfiguration config, ILogger <EnrichmentMessageRouter> logger)
        {
            this.dataSource      = dataSource;
            this.dataSink        = dataSink;
            this.dataEnricher    = dataEnricher;
            this.telemetryClient = telemetryClient;
            this.logger          = logger;
            this.config          = config;

            // handle messages as they arrive
            this.MessageBatchReceived += (sender, e) =>
            {
                // process with parallelism
                Parallel.ForEach(e.Messages, async(message) =>
                {
                    // get the device id
                    var deviceId = message.GetDeviceId();

                    // get the metadata
                    var startTime = DateTime.UtcNow;
                    var timer     = System.Diagnostics.Stopwatch.StartNew();
                    try
                    {
                        var metadata = await this.dataEnricher.GetMetadataAsync(deviceId);
                        if (metadata != null)
                        {
                            // enrich the message
                            message.EnrichMessage(metadata);

                            // output the message
                            await this.dataSink.WriteMessageAsync(message);

                            // send the telemetry
                            timer.Stop();
                            telemetryClient.TrackDependency("gRPC call", "IoTClient", "GetMetadataAzync", startTime, timer.Elapsed, true);
                        }
                    }
                    catch
                    {
                        // send the telemetry
                        timer.Stop();
                        logger.LogDebug($"gRPC call took {timer.Elapsed.Milliseconds} ms");
                        telemetryClient.TrackDependency("gRPC call", "IoTClient", "GetMetadataAzync", startTime, timer.Elapsed, false);
                    }
                    finally
                    {
                        Interlocked.Decrement(ref waiting);
                    }
                });
            };
        }
        public void TrackSendEmail(string smtpUri, DateTimeOffset startTime, TimeSpan duration, bool success, int attemptNumber)
        {
            var properties = new Dictionary <string, string>
            {
                { "attempt", attemptNumber.ToString() }
            };

            _telemetryClient.TrackDependency("SMTP", smtpUri, "SendMessage", null, startTime, duration, null, success, properties);
        }