diff --git a/src/OmniSharp.Roslyn.CSharp/DocumentationComments/DocumentationCommentSnippetService.cs b/src/OmniSharp.Roslyn.CSharp/DocumentationComments/DocumentationCommentSnippetService.cs
new file mode 100644
index 0000000000..8b72c8669c
--- /dev/null
+++ b/src/OmniSharp.Roslyn.CSharp/DocumentationComments/DocumentationCommentSnippetService.cs
@@ -0,0 +1,110 @@
+#nullable enable
+
+using System;
+using System.Reflection;
+using System.Threading;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.Completion;
+using Microsoft.CodeAnalysis.Host;
+using Microsoft.CodeAnalysis.Options;
+using Microsoft.CodeAnalysis.Text;
+
+namespace OmniSharp.Roslyn.DocumentationComments
+{
+ ///
+ /// Proxy service for Microsoft.CodeAnalysis.DocumentationComments.IDocumentationCommentSnippetService.
+ /// Implementation was based on the service as of this commit: 2834b74995bb66a7cb19cb09069c17812819afdc
+ /// See: https://github.com/dotnet/roslyn/blob/2834b74995bb66a7cb19cb09069c17812819afdc/src/Features/Core/Portable/DocumentationComments/IDocumentationCommentSnippetService.cs
+ ///
+ public struct DocumentationCommentSnippetService
+ {
+ ///
+ /// IDocumentationCommentService HostLanguageServices.GetRequiredService()
+ ///
+ private static MethodInfo s_getRequiredService;
+ ///
+ /// DocumentationCommentSnippet IDocumentationCommentService.GetDocumentationCommentSnippetOnCharacterTyped(SyntaxTree, SourceText, int, DocumentOptionSet, CancellationToken)
+ ///
+ private static MethodInfo s_getDocumentationCommentSnippetOnCharacterTyped;
+ ///
+ /// DocumentationCommentSnippet IDocumentationCommentService.GetDocumentationCommentSnippetOnEnterTyped(SyntaxTree, SourceText, int, DocumentOptionSet, CancellationToken)
+ ///
+ private static MethodInfo s_getDocumentationCommentSnippetOnEnterTyped;
+ ///
+ /// TextSpan DocumentationCommentSnippet.SpanToReplace
+ ///
+ private static PropertyInfo s_spanToReplace;
+ ///
+ /// string DocumentationCommentSnippet.SnippetText
+ ///
+ private static PropertyInfo s_snippetText;
+
+ static DocumentationCommentSnippetService()
+ {
+ var iDocumentationCommentSnippetServiceType = typeof(CompletionItem).Assembly.GetType("Microsoft.CodeAnalysis.DocumentationComments.IDocumentationCommentSnippetService");
+ s_getDocumentationCommentSnippetOnCharacterTyped = iDocumentationCommentSnippetServiceType.GetMethod(nameof(GetDocumentationCommentSnippetOnCharacterTyped));
+ s_getDocumentationCommentSnippetOnEnterTyped = iDocumentationCommentSnippetServiceType.GetMethod(nameof(GetDocumentationCommentSnippetOnEnterTyped));
+
+ var documentationCommentSnippet = typeof(CompletionItem).Assembly.GetType("Microsoft.CodeAnalysis.DocumentationComments.DocumentationCommentSnippet");
+ s_spanToReplace = documentationCommentSnippet.GetProperty(nameof(DocumentationCommentSnippet.SpanToReplace));
+ s_snippetText = documentationCommentSnippet.GetProperty(nameof(DocumentationCommentSnippet.SnippetText));
+
+ s_getRequiredService = typeof(HostLanguageServices).GetMethod(nameof(HostLanguageServices.GetRequiredService)).MakeGenericMethod(iDocumentationCommentSnippetServiceType);
+ }
+
+ public static DocumentationCommentSnippetService GetDocumentationCommentSnippetService(Document document)
+ {
+ var service = s_getRequiredService.Invoke(document.Project.LanguageServices, Array.Empty