private static IExportProviderFactory CreateRemoteHostExportProviderFactory() { var configuration = CompositionConfiguration.Create(ExportProviderCache.GetOrCreateAssemblyCatalog(RoslynServices.RemoteHostAssemblies).WithCompositionService()); var runtimeComposition = RuntimeComposition.CreateRuntimeComposition(configuration); return(runtimeComposition.CreateExportProviderFactory()); }
private IExportProviderFactory GetOrCreateFactory() { var key = new CacheKey(Assemblies, Parts, ExcludedPartTypes); lock (s_factoryCache) { if (s_factoryCache.TryGetValue(key, out var existing)) { return(existing); } } var newFactory = ExportProviderCache.CreateExportProviderFactory(GetCatalog(), IsRemote); lock (s_factoryCache) { if (s_factoryCache.TryGetValue(key, out var existing)) { return(existing); } s_factoryCache.Add(key, newFactory); } return(newFactory); }
private MefHostServices CreateMefHostServices(IEnumerable <Assembly> assemblies) { ExportProvider exportProvider; if (assemblies is ImmutableArray <Assembly> array && array == MefHostServices.DefaultAssemblies && ExportProviderCache.LocalExportProviderForCleanup != null) { if (_hostServices != null) { return(_hostServices); } exportProvider = ExportProviderCache.LocalExportProviderForCleanup; } else { exportProvider = ExportProviderCache.GetOrCreateExportProviderFactory(assemblies).CreateExportProvider(); } Interlocked.CompareExchange( ref _hostServices, new ExportProviderMefHostServices(exportProvider), null); return(_hostServices); }
/// <summary> /// To the extent reasonably possible, this method resets the state of the test environment to the same state as /// it started, ensuring that tests running in sequence cannot influence the outcome of later tests. /// </summary> /// <remarks> /// <para>The test cleanup runs in two primary steps:</para> /// <list type="number"> /// <item>Waiting for asynchronous operations started by the test to complete.</item> /// <item>Disposing of mutable resources created by the test.</item> /// <item>Clearing static state variables related to the use of MEF during a test.</item> /// </list> /// </remarks> public override void After(MethodInfo methodUnderTest) { var exportProvider = ExportProviderCache.ExportProviderForCleanup; try { var listenerProvider = exportProvider?.GetExportedValues <IAsynchronousOperationListenerProvider>().SingleOrDefault(); if (listenerProvider != null) { if (ForegroundThreadAffinitizedObject.CurrentForegroundThreadData.Kind != ForegroundThreadDataKind.Unknown) { // Immediately clear items from the foreground notification service for which cancellation is // requested. This service maintains a queue separately from Tasks, and work items scheduled for // execution after a delay are not immediately purged when cancellation is requested. This code // instructs the service to walk the list of queued work items and immediately cancel and purge any // which are already cancelled. var foregroundNotificationService = exportProvider?.GetExportedValues <IForegroundNotificationService>().SingleOrDefault() as ForegroundNotificationService; foregroundNotificationService?.ReleaseCancelledItems(); } // Join remaining operations with a timeout using (var timeoutTokenSource = new CancellationTokenSource(CleanupTimeout)) { try { var waiter = ((AsynchronousOperationListenerProvider)listenerProvider).WaitAllDispatcherOperationAndTasksAsync(); waiter.JoinUsingDispatcher(timeoutTokenSource.Token); } catch (OperationCanceledException ex) when(timeoutTokenSource.IsCancellationRequested) { var messageBuilder = new StringBuilder("Failed to clean up listeners in a timely manner."); foreach (var token in ((AsynchronousOperationListenerProvider)listenerProvider).GetTokens()) { messageBuilder.AppendLine().Append($" {token}"); } throw new TimeoutException(messageBuilder.ToString(), ex); } } } } finally { // Dispose of the export provider, including calling Dispose for any IDisposable services created during // the test. exportProvider?.Dispose(); // Replace hooks with ones that always throw exceptions. These hooks detect cases where code executing // after the end of a test attempts to create an ExportProvider. MefHostServices.HookServiceCreation(DenyMefHostServicesCreationBetweenTests); RoslynServices.HookHostServices(() => throw new InvalidOperationException("Cannot create host services after test tear down.")); // Reset static state variables. DesktopMefHostServices.ResetHostServicesTestOnly(); _hostServices = null; ExportProviderCache.SetEnabled_OnlyUseExportProviderAttributeCanCall(false); } }
public override void Before(MethodInfo methodUnderTest) { MefHostServices.TestAccessor.HookServiceCreation(CreateMefHostServices); // make sure we enable this for all unit tests AsynchronousOperationListenerProvider.Enable(enable: true, diagnostics: true); ExportProviderCache.SetEnabled_OnlyUseExportProviderAttributeCanCall(true); }
public override void Before(MethodInfo methodUnderTest) { MefHostServices.HookServiceCreation(CreateMefHostServices); RoslynServices.HookHostServices(() => _remoteHostServices.Value); DesktopMefHostServices.ResetHostServicesTestOnly(); // make sure we enable this for all unit tests AsynchronousOperationListenerProvider.Enable(enable: true, diagnostics: true); ExportProviderCache.SetEnabled_OnlyUseExportProviderAttributeCanCall(true); }
/// <summary> /// To the extent reasonably possible, this method resets the state of the test environment to the same state as /// it started, ensuring that tests running in sequence cannot influence the outcome of later tests. /// </summary> /// <remarks> /// <para>The test cleanup runs in two primary steps:</para> /// <list type="number"> /// <item>Waiting for asynchronous operations started by the test to complete.</item> /// <item>Disposing of mutable resources created by the test.</item> /// <item>Clearing static state variables related to the use of MEF during a test.</item> /// </list> /// </remarks> public override void After(MethodInfo methodUnderTest) { try { DisposeExportProvider(ExportProviderCache.LocalExportProviderForCleanup); DisposeExportProvider(ExportProviderCache.RemoteExportProviderForCleanup); } finally { // Replace hooks with ones that always throw exceptions. These hooks detect cases where code executing // after the end of a test attempts to create an ExportProvider. MefHostServices.TestAccessor.HookServiceCreation(DenyMefHostServicesCreationBetweenTests); // Reset static state variables. _hostServices = null; ExportProviderCache.SetEnabled_OnlyUseExportProviderAttributeCanCall(false); } }
private MefHostServices CreateMefHostServices(IEnumerable <Assembly> assemblies, bool requestingDefaultAssemblies) { if (requestingDefaultAssemblies && ExportProviderCache.ExportProviderForCleanup != null) { if (_hostServices == null) { var hostServices = new ExportProviderMefHostServices(ExportProviderCache.ExportProviderForCleanup); Interlocked.CompareExchange(ref _hostServices, hostServices, null); } return(_hostServices); } var catalog = ExportProviderCache.GetOrCreateAssemblyCatalog(assemblies); Interlocked.CompareExchange( ref _hostServices, new ExportProviderMefHostServices(ExportProviderCache.GetOrCreateExportProviderFactory(catalog).CreateExportProvider()), null); return(_hostServices); }
private ComposableCatalog GetCatalog() => ExportProviderCache.CreateAssemblyCatalog(Assemblies, ExportProviderCache.CreateResolver()).WithoutPartsOfTypes(ExcludedPartTypes).WithParts(Parts);
public override void After(MethodInfo methodUnderTest) { var exportProvider = ExportProviderCache.ExportProviderForCleanup; try { if (exportProvider?.GetExportedValues <IAsynchronousOperationListenerProvider>().SingleOrDefault() is { } listenerProvider) { if (exportProvider.GetExportedValues <IThreadingContext>().SingleOrDefault()?.HasMainThread ?? false) { // Immediately clear items from the foreground notification service for which cancellation is // requested. This service maintains a queue separately from Tasks, and work items scheduled for // execution after a delay are not immediately purged when cancellation is requested. This code // instructs the service to walk the list of queued work items and immediately cancel and purge any // which are already cancelled. var foregroundNotificationService = exportProvider.GetExportedValues <IForegroundNotificationService>().SingleOrDefault() as ForegroundNotificationService; foregroundNotificationService?.ReleaseCancelledItems(); } // Join remaining operations with a timeout using (var timeoutTokenSource = new CancellationTokenSource(CleanupTimeout)) { try { var waiter = ((AsynchronousOperationListenerProvider)listenerProvider).WaitAllDispatcherOperationAndTasksAsync(); waiter.JoinUsingDispatcher(timeoutTokenSource.Token); } catch (OperationCanceledException ex) when(timeoutTokenSource.IsCancellationRequested) { var messageBuilder = new StringBuilder("Failed to clean up listeners in a timely manner."); foreach (var token in ((AsynchronousOperationListenerProvider)listenerProvider).GetTokens()) { messageBuilder.AppendLine().Append($" {token}"); } throw new TimeoutException(messageBuilder.ToString(), ex); } } // Verify the synchronization context was not used incorrectly var testExportJoinableTaskContext = exportProvider.GetExportedValues <TestExportJoinableTaskContext>().SingleOrDefault(); if (testExportJoinableTaskContext?.SynchronizationContext is TestExportJoinableTaskContext.DenyExecutionSynchronizationContext synchronizationContext) { synchronizationContext.ThrowIfSwitchOccurred(); } foreach (var testErrorHandler in exportProvider.GetExportedValues <ITestErrorHandler>()) { var exceptions = testErrorHandler.Exceptions; if (exceptions.Count > 0) { throw new AggregateException("Tests threw unexpected exceptions", exceptions); } } } } finally { // Dispose of the export provider, including calling Dispose for any IDisposable services created during // the test. exportProvider?.Dispose(); // Replace hooks with ones that always throw exceptions. These hooks detect cases where code executing // after the end of a test attempts to create an ExportProvider. MefHostServices.TestAccessor.HookServiceCreation(DenyMefHostServicesCreationBetweenTests); RoslynServices.TestAccessor.HookHostServices(() => throw new InvalidOperationException("Cannot create host services after test tear down.")); // Reset static state variables. _hostServices = null; ExportProviderCache.SetEnabled_OnlyUseExportProviderAttributeCanCall(false); } }