提交 beeda553 编写于 作者: S Sam Harwell

Use MEF instead of constructor injection to configure IDocumentTrackingService for testing

上级 0097215c
......@@ -24,7 +24,6 @@ private class Searcher
{
private readonly Solution _solution;
private readonly IAsynchronousOperationListener _asyncListener;
private readonly IDocumentTrackingService _documentTrackingService;
private readonly INavigateToItemDisplayFactory _displayFactory;
private readonly INavigateToCallback _callback;
private readonly string _searchPattern;
......@@ -37,7 +36,6 @@ private class Searcher
public Searcher(
Solution solution,
IAsynchronousOperationListener asyncListener,
IDocumentTrackingService documentTrackingService,
INavigateToItemDisplayFactory displayFactory,
INavigateToCallback callback,
string searchPattern,
......@@ -47,7 +45,6 @@ private class Searcher
{
_solution = solution;
_asyncListener = asyncListener;
_documentTrackingService = documentTrackingService;
_displayFactory = displayFactory;
_callback = callback;
_searchPattern = searchPattern;
......@@ -78,7 +75,7 @@ internal async void Search()
// If the workspace is tracking documents, use that to prioritize our search
// order. That way we provide results for the documents the user is working
// on faster than the rest of the solution.
var docTrackingService = _documentTrackingService ?? workspace.Services.GetService<IDocumentTrackingService>();
var docTrackingService = workspace.Services.GetService<IDocumentTrackingService>();
if (docTrackingService != null)
{
await SearchProjectsInPriorityOrder(docTrackingService).ConfigureAwait(false);
......
......@@ -18,22 +18,19 @@ internal partial class NavigateToItemProvider : INavigateToItemProvider2
{
private readonly Workspace _workspace;
private readonly IAsynchronousOperationListener _asyncListener;
private readonly IDocumentTrackingService _documentTrackingService;
private readonly INavigateToItemDisplayFactory _displayFactory;
private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
public NavigateToItemProvider(
Workspace workspace,
IAsynchronousOperationListener asyncListener,
IDocumentTrackingService documentTrackingService)
IAsynchronousOperationListener asyncListener)
{
Contract.ThrowIfNull(workspace);
Contract.ThrowIfNull(asyncListener);
_workspace = workspace;
_asyncListener = asyncListener;
_documentTrackingService = documentTrackingService;
_displayFactory = new NavigateToItemDisplayFactory();
}
......@@ -145,7 +142,6 @@ private void StartSearch(INavigateToCallback callback, string searchValue, IImmu
var searcher = new Searcher(
_workspace.CurrentSolution,
_asyncListener,
_documentTrackingService,
_displayFactory,
callback,
searchValue,
......
......@@ -36,8 +36,7 @@ public bool TryCreateNavigateToItemProvider(IServiceProvider serviceProvider, ou
return false;
}
provider = new NavigateToItemProvider(
workspace, _asyncListener, documentTrackingService: null);
provider = new NavigateToItemProvider(workspace, _asyncListener);
return true;
}
}
......
......@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Media;
......@@ -12,6 +13,8 @@
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Editor.Wpf;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Remote;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.Test.Utilities;
......@@ -53,29 +56,37 @@ public abstract class AbstractNavigateToTests
internal readonly static PatternMatch s_emptyCamelCaseNonContiguousSubstringPatternMatch_NotCaseSensitive = new PatternMatch(PatternMatchKind.CamelCaseNonContiguousSubstring, true, false, ImmutableArray<Span>.Empty);
internal readonly static PatternMatch s_emptyFuzzyPatternMatch_NotCaseSensitive = new PatternMatch(PatternMatchKind.Fuzzy, true, false, ImmutableArray<Span>.Empty);
public static IEnumerable<object[]> TrackingServiceTypes
{
get
{
yield return new object[] { null };
yield return new object[] { typeof(FirstDocIsActiveDocumentTrackingService.Factory) };
yield return new object[] { typeof(FirstDocIsVisibleDocumentTrackingService.Factory) };
yield return new object[] { typeof(FirstDocIsActiveAndVisibleDocumentTrackingService.Factory) };
}
}
protected abstract TestWorkspace CreateWorkspace(string content, ExportProvider exportProvider);
protected abstract string Language { get; }
protected async Task TestAsync(string content, Func<TestWorkspace, Task> body)
protected async Task TestAsync(string content, Func<TestWorkspace, Task> body, Type trackingServiceType)
{
await TestAsync(content, body, outOfProcess: true);
await TestAsync(content, body, outOfProcess: false);
}
var catalog = TestExportProvider.EntireAssemblyCatalogWithCSharpAndVisualBasic;
if (trackingServiceType != null)
{
catalog = catalog.WithPart(trackingServiceType);
}
internal async Task TestAsync(string content, Func<TestWorkspace, Task> body, bool outOfProcess)
{
await TestAsync(content, body, outOfProcess, null);
await TestAsync(content, body, outOfProcess, w => new FirstDocIsActiveDocumentTrackingService(w));
await TestAsync(content, body, outOfProcess, w => new FirstDocIsVisibleDocumentTrackingService(w));
await TestAsync(content, body, outOfProcess, w => new FirstDocIsActiveAndVisibleDocumentTrackingService(w));
var exportProvider = ExportProviderCache.GetOrCreateExportProviderFactory(catalog).CreateExportProvider();
await TestAsync(content, body, outOfProcess: true, exportProvider);
await TestAsync(content, body, outOfProcess: false, exportProvider);
}
internal async Task TestAsync(
string content, Func<TestWorkspace, Task> body, bool outOfProcess,
Func<TestWorkspace, IDocumentTrackingService> createTrackingService)
internal async Task TestAsync(string content, Func<TestWorkspace, Task> body, bool outOfProcess, ExportProvider exportProvider)
{
using (var workspace = SetupWorkspace(
content, TestExportProvider.ExportProviderWithCSharpAndVisualBasic, createTrackingService))
using (var workspace = SetupWorkspace(content, exportProvider))
{
workspace.Options = workspace.Options.WithChangedOption(RemoteHostOptions.RemoteHostTest, outOfProcess)
.WithChangedOption(RemoteFeatureOptions.OutOfProcessAllowed, outOfProcess)
......@@ -85,30 +96,23 @@ internal async Task TestAsync(string content, Func<TestWorkspace, Task> body, bo
}
}
private protected TestWorkspace SetupWorkspace(
XElement workspaceElement, ExportProvider exportProvider,
Func<TestWorkspace, IDocumentTrackingService> createTrackingService)
private protected TestWorkspace SetupWorkspace(XElement workspaceElement, ExportProvider exportProvider)
{
var workspace = TestWorkspace.Create(workspaceElement, exportProvider: exportProvider);
var trackingService = createTrackingService?.Invoke(workspace);
InitializeWorkspace(workspace, trackingService);
InitializeWorkspace(workspace);
return workspace;
}
private protected TestWorkspace SetupWorkspace(
string content, ExportProvider exportProvider,
Func<TestWorkspace, IDocumentTrackingService> createTrackingService)
private protected TestWorkspace SetupWorkspace(string content, ExportProvider exportProvider)
{
var workspace = CreateWorkspace(content, exportProvider);
var trackingService = createTrackingService?.Invoke(workspace);
InitializeWorkspace(workspace, trackingService);
InitializeWorkspace(workspace);
return workspace;
}
internal void InitializeWorkspace(
TestWorkspace workspace, IDocumentTrackingService documentTrackingService)
internal void InitializeWorkspace(TestWorkspace workspace)
{
_provider = new NavigateToItemProvider(workspace, AsynchronousOperationListenerProvider.NullListener, documentTrackingService);
_provider = new NavigateToItemProvider(workspace, AsynchronousOperationListenerProvider.NullListener);
_aggregator = new NavigateToTestAggregator(_provider);
}
......@@ -202,6 +206,7 @@ public class FirstDocIsActiveDocumentTrackingService : IDocumentTrackingService
{
private readonly Workspace _workspace;
[Obsolete(MefConstruction.FactoryMethodMessage, error: true)]
public FirstDocIsActiveDocumentTrackingService(Workspace workspace)
{
_workspace = workspace;
......@@ -215,12 +220,31 @@ public DocumentId GetActiveDocument()
public ImmutableArray<DocumentId> GetVisibleDocuments()
=> ImmutableArray<DocumentId>.Empty;
[ExportWorkspaceServiceFactory(typeof(IDocumentTrackingService), ServiceLayer.Host)]
[Shared]
[PartNotDiscoverable]
public sealed class Factory : IWorkspaceServiceFactory
{
[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public Factory()
{
}
[Obsolete(MefConstruction.FactoryMethodMessage, error: true)]
public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices)
{
return new FirstDocIsActiveDocumentTrackingService(workspaceServices.Workspace);
}
}
}
public class FirstDocIsVisibleDocumentTrackingService : IDocumentTrackingService
{
private readonly Workspace _workspace;
[Obsolete(MefConstruction.FactoryMethodMessage, error: true)]
public FirstDocIsVisibleDocumentTrackingService(Workspace workspace)
{
_workspace = workspace;
......@@ -234,12 +258,31 @@ public DocumentId GetActiveDocument()
public ImmutableArray<DocumentId> GetVisibleDocuments()
=> ImmutableArray.Create(_workspace.CurrentSolution.Projects.First().DocumentIds.First());
[ExportWorkspaceServiceFactory(typeof(IDocumentTrackingService), ServiceLayer.Host)]
[Shared]
[PartNotDiscoverable]
public sealed class Factory : IWorkspaceServiceFactory
{
[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public Factory()
{
}
[Obsolete(MefConstruction.FactoryMethodMessage, error: true)]
public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices)
{
return new FirstDocIsVisibleDocumentTrackingService(workspaceServices.Workspace);
}
}
}
public class FirstDocIsActiveAndVisibleDocumentTrackingService : IDocumentTrackingService
{
private readonly Workspace _workspace;
[Obsolete(MefConstruction.FactoryMethodMessage, error: true)]
public FirstDocIsActiveAndVisibleDocumentTrackingService(Workspace workspace)
{
_workspace = workspace;
......@@ -253,5 +296,23 @@ public DocumentId GetActiveDocument()
public ImmutableArray<DocumentId> GetVisibleDocuments()
=> ImmutableArray.Create(_workspace.CurrentSolution.Projects.First().DocumentIds.First());
[ExportWorkspaceServiceFactory(typeof(IDocumentTrackingService), ServiceLayer.Host)]
[Shared]
[PartNotDiscoverable]
public sealed class Factory : IWorkspaceServiceFactory
{
[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public Factory()
{
}
[Obsolete(MefConstruction.FactoryMethodMessage, error: true)]
public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices)
{
return new FirstDocIsActiveAndVisibleDocumentTrackingService(workspaceServices.Workspace);
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册