/// <summary>
        /// Creates an instance of the <see cref="AgentManager"/> class./>
        /// </summary>
        /// <remarks>
        /// The agent should be constructed as early as possible in order to perform
        /// initialization of the logging system.
        /// </remarks>
        private AgentManager()
        {
            _container = AgentServices.GetContainer();
            AgentServices.RegisterServices(_container);

            // Resolve IConfigurationService (so that it starts listening to config changes) before loading newrelic.config
            _container.Resolve <IConfigurationService>();
            var config = ConfigurationLoader.Initialize();

            LoggerBootstrapper.ConfigureLogger(config.LogConfig);

            AssertAgentEnabled(config);

            EventBus <KillAgentEvent> .Subscribe(OnShutdownAgent);

            //Initialize the extensions loader with extensions folder based on the the install path
            ExtensionsLoader.Initialize(AgentInstallConfiguration.InstallPathExtensionsDirectory);

            // Resolve all services once we've ensured that the agent is enabled
            // The AgentApiImplementation needs to be resolved before the WrapperService, because
            // resolving the WrapperService triggers an agent connect but it doesn't instantiate
            // the CustomEventAggregator, so we need to resolve the AgentApiImplementation to
            // get the CustomEventAggregator instantiated before the connect process is triggered.
            // If that doesn't happen the CustomEventAggregator will not start its harvest timer
            // when the agent connect response comes back. The agent DI, startup, and connect
            // process really needs to be refactored so that it's more explicit in its behavior.
            var agentApi = _container.Resolve <IAgentApi>();

            _wrapperService = _container.Resolve <IWrapperService>();

            //We need to attempt to auto start the agent once all services have resolved
            _container.Resolve <IConnectionManager>().AttemptAutoStart();

            AgentServices.StartServices(_container);

            // Setup the internal API first so that AgentApi can use it.
            InternalApi.SetAgentApiImplementation(agentApi);
            AgentApi.SetSupportabilityMetricCounters(_container.Resolve <IApiSupportabilityMetricCounters>());

            Initialize();
            _isInitialized = true;
        }
        public CompositeTestAgent(bool shouldAllowThreads, bool includeAsyncLocalStorage)
        {
            Log.Initialize(new Logger());

            _shouldAllowThreads = shouldAllowThreads;

            // Create the fake classes necessary to construct services

            var mockFactory = Mock.Create <IContextStorageFactory>();

            Mock.Arrange(() => mockFactory.CreateContext <IInternalTransaction>(Arg.AnyString)).Returns(_primaryTransactionContextStorage);
            var transactionContextFactories = new List <IContextStorageFactory> {
                mockFactory
            };

            if (includeAsyncLocalStorage)
            {
                transactionContextFactories.Add(new AsyncLocalStorageFactory());
            }

            var wrappers             = Enumerable.Empty <IWrapper>();
            var mockEnvironment      = Mock.Create <IEnvironment>();
            var dataTransportService = Mock.Create <IDataTransportService>();
            var scheduler            = Mock.Create <IScheduler>();

            NativeMethods   = Mock.Create <INativeMethods>();
            _harvestActions = new List <Action>();
            Mock.Arrange(() => scheduler.ExecuteEvery(Arg.IsAny <Action>(), Arg.IsAny <TimeSpan>(), Arg.IsAny <TimeSpan?>()))
            .DoInstead <Action, TimeSpan, TimeSpan?>((action, _, __) => { lock (_harvestActionsLockObject) { _harvestActions.Add(action); } });
            var threadPoolStatic = Mock.Create <IThreadPoolStatic>();

            _queuedCallbacks = new List <WaitCallback>();
            Mock.Arrange(() => threadPoolStatic.QueueUserWorkItem(Arg.IsAny <WaitCallback>()))
            .DoInstead <WaitCallback>(callback => { lock (_queuedCallbacksLockObject) { _queuedCallbacks.Add(callback); } });

            var configurationManagerStatic = Mock.Create <IConfigurationManagerStatic>();

            Mock.Arrange(() => configurationManagerStatic.GetAppSetting("NewRelic.LicenseKey"))
            .Returns("Composite test license key");

            // Construct services
            _container = AgentServices.GetContainer();
            AgentServices.RegisterServices(_container);

            // Replace existing registrations with mocks before resolving any services
            _container.ReplaceRegistration(mockEnvironment);
            _container.ReplaceRegistration <IEnumerable <IContextStorageFactory> >(transactionContextFactories);
            _container.ReplaceRegistration <ICallStackManagerFactory>(
                new TestCallStackManagerFactory());
            _container.ReplaceRegistration(wrappers);
            _container.ReplaceRegistration(dataTransportService);
            _container.ReplaceRegistration(scheduler);
            _container.ReplaceRegistration(NativeMethods);

            _container.ReplaceRegistration(Mock.Create <ICATSupportabilityMetricCounters>());

            if (!_shouldAllowThreads)
            {
                _container.ReplaceRegistration(threadPoolStatic);
            }

            _container.ReplaceRegistration(configurationManagerStatic);

            InstrumentationService = _container.Resolve <IInstrumentationService>();
            InstrumentationWatcher = _container.Resolve <InstrumentationWatcher>();
            AgentServices.StartServices(_container);

            DisableAgentInitializer();
            InternalApi.SetAgentApiImplementation(_container.Resolve <IAgentApi>());
            AgentApi.SetSupportabilityMetricCounters(_container.Resolve <IApiSupportabilityMetricCounters>());

            // Update configuration (will also start services)
            LocalConfiguration    = GetDefaultTestLocalConfiguration();
            ServerConfiguration   = GetDefaultTestServerConfiguration();
            SecurityConfiguration = GetDefaultSecurityPoliciesConfiguration();
            InstrumentationWatcher.Start();
            PushConfiguration();

            _attribDefSvc = _container.Resolve <IAttributeDefinitionService>();

            // Redirect the mock DataTransportService to capture harvested wire models
            Mock.Arrange(() => dataTransportService.Send(Arg.IsAny <IEnumerable <MetricWireModel> >()))
            .Returns(SaveDataAndReturnSuccess(Metrics));
            Mock.Arrange(() => dataTransportService.Send(Arg.IsAny <IEnumerable <CustomEventWireModel> >()))
            .Returns(SaveDataAndReturnSuccess(CustomEvents));
            Mock.Arrange(() => dataTransportService.Send(Arg.IsAny <IEnumerable <TransactionTraceWireModel> >()))
            .Returns(SaveDataAndReturnSuccess(TransactionTraces));
            Mock.Arrange(() => dataTransportService.Send(Arg.IsAny <EventHarvestData>(), Arg.IsAny <IEnumerable <TransactionEventWireModel> >()))
            .Returns(SaveDataAndReturnSuccess(AdditionalHarvestData, TransactionEvents));
            Mock.Arrange(() => dataTransportService.Send(Arg.IsAny <IEnumerable <ErrorTraceWireModel> >()))
            .Returns(SaveDataAndReturnSuccess(ErrorTraces));
            Mock.Arrange(() => dataTransportService.Send(Arg.IsAny <IEnumerable <SqlTraceWireModel> >()))
            .Returns(SaveDataAndReturnSuccess(SqlTraces));
            Mock.Arrange(() => dataTransportService.Send(Arg.IsAny <EventHarvestData>(), Arg.IsAny <IEnumerable <ErrorEventWireModel> >()))
            .Returns(SaveDataAndReturnSuccess(AdditionalHarvestData, ErrorEvents));
            Mock.Arrange(() => dataTransportService.Send(Arg.IsAny <EventHarvestData>(), Arg.IsAny <IEnumerable <ISpanEventWireModel> >()))
            .Returns(SaveDataAndReturnSuccess(AdditionalHarvestData, SpanEvents));

            EnableAggregators();
        }