diff --git a/src/Microsoft.CodeAnalysis.Razor.Workspaces/ForegroundDispatcher.cs b/src/Microsoft.CodeAnalysis.Razor.Workspaces/ForegroundDispatcher.cs
new file mode 100644
index 0000000000..e9f9ca61eb
--- /dev/null
+++ b/src/Microsoft.CodeAnalysis.Razor.Workspaces/ForegroundDispatcher.cs
@@ -0,0 +1,32 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Runtime.CompilerServices;
+using Microsoft.CodeAnalysis.Host;
+
+namespace Microsoft.CodeAnalysis.Razor
+{
+ internal abstract class ForegroundDispatcher : IWorkspaceService
+ {
+ public abstract bool IsForegroundThread { get; }
+
+ public virtual void AssertForegroundThread([CallerMemberName] string caller = null)
+ {
+ if (!IsForegroundThread)
+ {
+ caller = caller == null ? Workspaces.Resources.ForegroundDispatcher_NoMethodNamePlaceholder : $"'{caller}'";
+ throw new InvalidOperationException(Workspaces.Resources.FormatForegroundDispatcher_AssertForegroundThread(caller));
+ }
+ }
+
+ public virtual void AssertBackgroundThread([CallerMemberName] string caller = null)
+ {
+ if (IsForegroundThread)
+ {
+ caller = caller == null ? Workspaces.Resources.ForegroundDispatcher_NoMethodNamePlaceholder : $"'{caller}'";
+ throw new InvalidOperationException(Workspaces.Resources.FormatForegroundDispatcher_AssertBackgroundThread(caller));
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.CodeAnalysis.Razor.Workspaces/Properties/Resources.Designer.cs b/src/Microsoft.CodeAnalysis.Razor.Workspaces/Properties/Resources.Designer.cs
new file mode 100644
index 0000000000..058b78c6ed
--- /dev/null
+++ b/src/Microsoft.CodeAnalysis.Razor.Workspaces/Properties/Resources.Designer.cs
@@ -0,0 +1,86 @@
+//
+namespace Microsoft.CodeAnalysis.Razor.Workspaces
+{
+ using System.Globalization;
+ using System.Reflection;
+ using System.Resources;
+
+ internal static class Resources
+ {
+ private static readonly ResourceManager _resourceManager
+ = new ResourceManager("Microsoft.CodeAnalysis.Razor.Workspaces.Resources", typeof(Resources).GetTypeInfo().Assembly);
+
+ ///
+ /// Value cannot be null or an empty string.
+ ///
+ internal static string ArgumentCannotBeNullOrEmpty
+ {
+ get => GetString("ArgumentCannotBeNullOrEmpty");
+ }
+
+ ///
+ /// Value cannot be null or an empty string.
+ ///
+ internal static string FormatArgumentCannotBeNullOrEmpty()
+ => GetString("ArgumentCannotBeNullOrEmpty");
+
+ ///
+ /// {0} must be called on a background thread.
+ ///
+ internal static string ForegroundDispatcher_AssertBackgroundThread
+ {
+ get => GetString("ForegroundDispatcher_AssertBackgroundThread");
+ }
+
+ ///
+ /// {0} must be called on a background thread.
+ ///
+ internal static string FormatForegroundDispatcher_AssertBackgroundThread(object p0)
+ => string.Format(CultureInfo.CurrentCulture, GetString("ForegroundDispatcher_AssertBackgroundThread"), p0);
+
+ ///
+ /// {0} must be called on the foreground thread.
+ ///
+ internal static string ForegroundDispatcher_AssertForegroundThread
+ {
+ get => GetString("ForegroundDispatcher_AssertForegroundThread");
+ }
+
+ ///
+ /// {0} must be called on the foreground thread.
+ ///
+ internal static string FormatForegroundDispatcher_AssertForegroundThread(object p0)
+ => string.Format(CultureInfo.CurrentCulture, GetString("ForegroundDispatcher_AssertForegroundThread"), p0);
+
+ ///
+ /// The method
+ ///
+ internal static string ForegroundDispatcher_NoMethodNamePlaceholder
+ {
+ get => GetString("ForegroundDispatcher_NoMethodNamePlaceholder");
+ }
+
+ ///
+ /// The method
+ ///
+ internal static string FormatForegroundDispatcher_NoMethodNamePlaceholder()
+ => GetString("ForegroundDispatcher_NoMethodNamePlaceholder");
+
+ private static string GetString(string name, params string[] formatterNames)
+ {
+ var value = _resourceManager.GetString(name);
+
+ System.Diagnostics.Debug.Assert(value != null);
+
+ if (formatterNames != null)
+ {
+ for (var i = 0; i < formatterNames.Length; i++)
+ {
+ value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}");
+ }
+ }
+
+ return value;
+ }
+ }
+}
diff --git a/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources.resx b/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources.resx
new file mode 100644
index 0000000000..fca5a30e15
--- /dev/null
+++ b/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources.resx
@@ -0,0 +1,132 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Value cannot be null or an empty string.
+
+
+ {0} must be called on a background thread.
+
+
+ {0} must be called on the foreground thread.
+
+
+ The method
+
+
\ No newline at end of file
diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Editor/VisualStudioRazorParser.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Editor/VisualStudioRazorParser.cs
index 106efbca51..6bbd900efd 100644
--- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Editor/VisualStudioRazorParser.cs
+++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/Editor/VisualStudioRazorParser.cs
@@ -5,6 +5,7 @@ using System;
using System.Timers;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Legacy;
+using Microsoft.CodeAnalysis.Razor;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/ForegroundDispatcher.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/ForegroundDispatcher.cs
deleted file mode 100644
index 712cf635a6..0000000000
--- a/src/Microsoft.VisualStudio.LanguageServices.Razor/ForegroundDispatcher.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Runtime.CompilerServices;
-
-namespace Microsoft.VisualStudio.LanguageServices.Razor
-{
- internal abstract class ForegroundDispatcher
- {
- public abstract bool IsForegroundThread { get; }
-
- public virtual void AssertForegroundThread([CallerMemberName] string caller = null)
- {
- if (!IsForegroundThread)
- {
- caller = caller == null ? Resources.ForegroundDispatcher_NoMethodNamePlaceholder : $"'{caller}'";
- throw new InvalidOperationException(Resources.FormatForegroundDispatcher_AssertForegroundThread(caller));
- }
- }
-
- public virtual void AssertBackgroundThread([CallerMemberName] string caller = null)
- {
- if (IsForegroundThread)
- {
- caller = caller == null ? Resources.ForegroundDispatcher_NoMethodNamePlaceholder : $"'{caller}'";
- throw new InvalidOperationException(Resources.FormatForegroundDispatcher_AssertBackgroundThread(caller));
- }
- }
- }
-}
diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Properties/Resources.Designer.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Properties/Resources.Designer.cs
index f137c477f1..2237686c54 100644
--- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Properties/Resources.Designer.cs
+++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/Properties/Resources.Designer.cs
@@ -24,48 +24,6 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor
internal static string FormatArgumentCannotBeNullOrEmpty()
=> GetString("ArgumentCannotBeNullOrEmpty");
- ///
- /// {0} must be called on a background thread.
- ///
- internal static string ForegroundDispatcher_AssertBackgroundThread
- {
- get => GetString("ForegroundDispatcher_AssertBackgroundThread");
- }
-
- ///
- /// {0} must be called on a background thread.
- ///
- internal static string FormatForegroundDispatcher_AssertBackgroundThread(object p0)
- => string.Format(CultureInfo.CurrentCulture, GetString("ForegroundDispatcher_AssertBackgroundThread"), p0);
-
- ///
- /// {0} must be called on the foreground thread.
- ///
- internal static string ForegroundDispatcher_AssertForegroundThread
- {
- get => GetString("ForegroundDispatcher_AssertForegroundThread");
- }
-
- ///
- /// {0} must be called on the foreground thread.
- ///
- internal static string FormatForegroundDispatcher_AssertForegroundThread(object p0)
- => string.Format(CultureInfo.CurrentCulture, GetString("ForegroundDispatcher_AssertForegroundThread"), p0);
-
- ///
- /// The method
- ///
- internal static string ForegroundDispatcher_NoMethodNamePlaceholder
- {
- get => GetString("ForegroundDispatcher_NoMethodNamePlaceholder");
- }
-
- ///
- /// The method
- ///
- internal static string FormatForegroundDispatcher_NoMethodNamePlaceholder()
- => GetString("ForegroundDispatcher_NoMethodNamePlaceholder");
-
///
/// An unexpected exception occurred when invoking '{0}.{1}' on the Razor language service.
///
diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Resources.resx b/src/Microsoft.VisualStudio.LanguageServices.Razor/Resources.resx
index 3dfcb98b6f..87f559339f 100644
--- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Resources.resx
+++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/Resources.resx
@@ -120,15 +120,6 @@
Value cannot be null or an empty string.
-
- {0} must be called on a background thread.
-
-
- {0} must be called on the foreground thread.
-
-
- The method
-
An unexpected exception occurred when invoking '{0}.{1}' on the Razor language service.
diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/VisualStudioForegroundDispatcher.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/VisualStudioForegroundDispatcher.cs
index 1a8ab11930..72e27447a5 100644
--- a/src/Microsoft.VisualStudio.LanguageServices.Razor/VisualStudioForegroundDispatcher.cs
+++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/VisualStudioForegroundDispatcher.cs
@@ -1,12 +1,15 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-using System.ComponentModel.Composition;
+using System.Composition;
+using Microsoft.CodeAnalysis.Host.Mef;
+using Microsoft.CodeAnalysis.Razor;
using Microsoft.VisualStudio.Shell;
namespace Microsoft.VisualStudio.LanguageServices.Razor
{
- [Export(typeof(ForegroundDispatcher))]
+ [Shared]
+ [ExportWorkspaceService(typeof(ForegroundDispatcher), ServiceLayer.Host)]
internal class VisualStudioForegroundDispatcher : ForegroundDispatcher
{
public override bool IsForegroundThread => ThreadHelper.CheckAccess();
diff --git a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ForegroundDispatcherTestBase.cs b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ForegroundDispatcherTestBase.cs
index dbe8bbdae0..3c7d626984 100644
--- a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ForegroundDispatcherTestBase.cs
+++ b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ForegroundDispatcherTestBase.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading;
+using Microsoft.CodeAnalysis.Razor;
namespace Microsoft.VisualStudio.LanguageServices.Razor
{