mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-13 17:23:02 -05:00
Adding completion extension loading and execution logic (#833)
* Adding ICompletionExtension interface * Adding extension loading and execution logic * Fixing compilation error in VS 2017 * Using MEF for completion extension discovery * using await on GetCompletionItems * Adding an integration test for completion extension and update the completion extension interface * Update the completion extension test * Fix issues based on review comments * Remove try/cache based on review comments, fix a integration test. * More changes based on review comments * Fixing SendResult logic for completion extension loading * Only load completion extension from the assembly passed in, add more comments in the test * Adding right assert messages in the test. * More fixes based on review comments * Dropping ICompletionExtensionProvider, load assembly only if it's loaded at the first time or updated since last load. * Fix based on the latest review comments * Adding missing TSQL functions in default completion list * Update jsonrpc documentation for completion/extLoad
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Composition.Convention;
|
||||
using System.Composition.Hosting;
|
||||
@@ -19,7 +20,7 @@ namespace Microsoft.SqlTools.Extensibility
|
||||
{
|
||||
public class ExtensionServiceProvider : RegisteredServiceProvider
|
||||
{
|
||||
private static readonly string[] defaultInclusionList =
|
||||
private static readonly string[] defaultInclusionList =
|
||||
{
|
||||
"microsofsqltoolscredentials.dll",
|
||||
"microsoft.sqltools.hosting.dll",
|
||||
@@ -36,8 +37,8 @@ namespace Microsoft.SqlTools.Extensibility
|
||||
|
||||
public static ExtensionServiceProvider CreateDefaultServiceProvider(string[] inclusionList = null)
|
||||
{
|
||||
// only allow loading MEF dependencies from our assemblies until we can
|
||||
// better seperate out framework assemblies and extension assemblies
|
||||
// only allow loading MEF dependencies from our assemblies until we can
|
||||
// better seperate out framework assemblies and extension assemblies
|
||||
return CreateFromAssembliesInDirectory(inclusionList ?? defaultInclusionList);
|
||||
}
|
||||
|
||||
@@ -114,8 +115,24 @@ namespace Microsoft.SqlTools.Extensibility
|
||||
base.Register<T>(() => store.GetExports<T>());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Merges in new assemblies to the existing container configuration.
|
||||
/// </summary>
|
||||
public void AddAssembliesToConfiguration(IEnumerable<Assembly> assemblies)
|
||||
{
|
||||
Validate.IsNotNull(nameof(assemblies), assemblies);
|
||||
var previousConfig = config;
|
||||
this.config = conventions => {
|
||||
// Chain in the existing configuration function's result, then include additional
|
||||
// assemblies
|
||||
ContainerConfiguration containerConfig = previousConfig(conventions);
|
||||
return containerConfig.WithAssemblies(assemblies, conventions);
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A store for MEF exports of a specific type. Provides basic wrapper functionality around MEF to standarize how
|
||||
/// we lookup types and return to callers.
|
||||
@@ -125,7 +142,7 @@ namespace Microsoft.SqlTools.Extensibility
|
||||
private CompositionHost host;
|
||||
private IList exports;
|
||||
private Type contractType;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the store with a type to lookup exports of, and a function that configures the
|
||||
/// lookup parameters.
|
||||
@@ -150,7 +167,7 @@ namespace Microsoft.SqlTools.Extensibility
|
||||
{
|
||||
return CreateAssemblyStore<T>(typeof(ExtensionStore).GetTypeInfo().Assembly);
|
||||
}
|
||||
|
||||
|
||||
public static ExtensionStore CreateAssemblyStore<T>(Assembly assembly)
|
||||
{
|
||||
Validate.IsNotNull(nameof(assembly), assembly);
|
||||
@@ -162,7 +179,7 @@ namespace Microsoft.SqlTools.Extensibility
|
||||
{
|
||||
string assemblyPath = typeof(ExtensionStore).GetTypeInfo().Assembly.Location;
|
||||
string directory = Path.GetDirectoryName(assemblyPath);
|
||||
return new ExtensionStore(typeof(T), (conventions) =>
|
||||
return new ExtensionStore(typeof(T), (conventions) =>
|
||||
new ContainerConfiguration().WithAssembliesInPath(directory, conventions));
|
||||
}
|
||||
|
||||
@@ -174,7 +191,7 @@ namespace Microsoft.SqlTools.Extensibility
|
||||
}
|
||||
return exports.Cast<T>();
|
||||
}
|
||||
|
||||
|
||||
private ConventionBuilder GetExportBuilder()
|
||||
{
|
||||
// Define exports as matching a parent type, export as that parent type
|
||||
@@ -183,7 +200,7 @@ namespace Microsoft.SqlTools.Extensibility
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class ContainerConfigurationExtensions
|
||||
{
|
||||
public static ContainerConfiguration WithAssembliesInPath(this ContainerConfiguration configuration, string path, SearchOption searchOption = SearchOption.TopDirectoryOnly)
|
||||
@@ -230,7 +247,7 @@ namespace Microsoft.SqlTools.Extensibility
|
||||
var apiApplicationFileInfo = new FileInfo($"{folderPath}{Path.DirectorySeparatorChar}{assemblyName.Name}.dll");
|
||||
if (File.Exists(apiApplicationFileInfo.FullName))
|
||||
{
|
||||
// Creating a new AssemblyContext instance for the same folder puts us at risk
|
||||
// Creating a new AssemblyContext instance for the same folder puts us at risk
|
||||
// of loading the same DLL in multiple contexts, which leads to some unpredictable
|
||||
// behavior in the loader. See https://github.com/dotnet/coreclr/issues/19632
|
||||
|
||||
|
||||
Reference in New Issue
Block a user