diff --git a/Directory.Build.targets b/Directory.Build.targets
index 4575754d0..a120fa374 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -17,6 +17,9 @@
+
+
+
@@ -45,4 +48,4 @@
-
\ No newline at end of file
+
diff --git a/src/Client/LanguageClientOptions.cs b/src/Client/LanguageClientOptions.cs
index ba77406c8..69483f8f2 100644
--- a/src/Client/LanguageClientOptions.cs
+++ b/src/Client/LanguageClientOptions.cs
@@ -18,6 +18,7 @@ public LanguageClientOptions()
{
WithAssemblies(typeof(LanguageClientOptions).Assembly, typeof(LspRequestRouter).Assembly);
}
+
public ClientCapabilities ClientCapabilities { get; set; } = new ClientCapabilities {
Experimental = new Dictionary(),
Window = new WindowClientCapabilities(),
@@ -52,7 +53,8 @@ ILanguageClientRegistry IJsonRpcHandlerRegistry.AddHand
ILanguageClientRegistry IJsonRpcHandlerRegistry.AddHandler(JsonRpcHandlerFactory handlerFunc, JsonRpcHandlerOptions? options) =>
AddHandler(handlerFunc, options);
- ILanguageClientRegistry IJsonRpcHandlerRegistry.AddHandler(IJsonRpcHandler handler, JsonRpcHandlerOptions? options) => AddHandler(handler, options);
+ ILanguageClientRegistry IJsonRpcHandlerRegistry.AddHandler(IJsonRpcHandler handler, JsonRpcHandlerOptions? options) =>
+ AddHandler(handler, options);
ILanguageClientRegistry IJsonRpcHandlerRegistry.AddHandler(JsonRpcHandlerOptions? options) => AddHandler(options);
diff --git a/src/Client/LanguageClientServiceCollectionExtensions.cs b/src/Client/LanguageClientServiceCollectionExtensions.cs
index 7fec5fc1d..3f4564135 100644
--- a/src/Client/LanguageClientServiceCollectionExtensions.cs
+++ b/src/Client/LanguageClientServiceCollectionExtensions.cs
@@ -3,6 +3,7 @@
using System.Linq;
using System.Reflection;
using DryIoc;
+using MediatR;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
@@ -28,7 +29,7 @@ internal static IContainer AddLanguageClientInternals(this IContainer container,
nonPublicServiceTypes: true,
ifAlreadyRegistered: IfAlreadyRegistered.Keep
);
- if (!EqualityComparer.Default.Equals( options.OnUnhandledException, default))
+ if (!EqualityComparer.Default.Equals(options.OnUnhandledException, default))
{
container.RegisterInstance(options.OnUnhandledException);
}
@@ -79,7 +80,7 @@ internal static IContainer AddLanguageClientInternals(this IContainer container,
if (providedConfiguration != null)
{
- builder.CustomAddConfiguration((providedConfiguration.ImplementationInstance as IConfiguration)!);
+ builder.CustomAddConfiguration(( providedConfiguration.ImplementationInstance as IConfiguration )!);
}
//var didChangeConfigurationProvider = _.GetRequiredService();
diff --git a/src/JsonRpc.Generators/GenerateHandlerMethodsGenerator.cs b/src/JsonRpc.Generators/GenerateHandlerMethodsGenerator.cs
index b5075b059..a207514ae 100644
--- a/src/JsonRpc.Generators/GenerateHandlerMethodsGenerator.cs
+++ b/src/JsonRpc.Generators/GenerateHandlerMethodsGenerator.cs
@@ -171,8 +171,9 @@ MemberDeclarationSyntax MakeAction(TypeSyntax syntax)
yield return MakeAction(CreateAsyncAction(true, requestType));
if (capability != null)
{
- yield return MakeAction(CreateAction(requestType, capability));
- yield return MakeAction(CreateAsyncAction(requestType, capability));
+ method = method.WithExpressionBody(
+ GetNotificationCapabilityHandlerExpression(GetMethodName(handlerInterface), requestType, capability)
+ );
yield return MakeAction(CreateAction(requestType, capability));
yield return MakeAction(CreateAsyncAction(requestType, capability));
}
diff --git a/src/JsonRpc/JsonRpcServerServiceCollectionExtensions.cs b/src/JsonRpc/JsonRpcServerServiceCollectionExtensions.cs
index 234193771..b27a6e475 100644
--- a/src/JsonRpc/JsonRpcServerServiceCollectionExtensions.cs
+++ b/src/JsonRpc/JsonRpcServerServiceCollectionExtensions.cs
@@ -1,6 +1,8 @@
using System;
using System.IO.Pipelines;
using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
using DryIoc;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
@@ -79,23 +81,51 @@ internal static IContainer AddJsonRpcMediatR(this IContainer container)
container.RegisterMany(new[] { typeof(IMediator).GetAssembly() }, Registrator.Interfaces, Reuse.ScopedOrSingleton);
container.RegisterMany(Reuse.Scoped);
container.RegisterDelegate(context => context.Resolve, Reuse.ScopedOrSingleton);
+ container.Register(typeof(IRequestHandler<,>), typeof(RequestHandler<,>));
+ container.Register(typeof(IRequestHandler<,>), typeof(RequestHandlerDecorator<,>), setup: Setup.Decorator);
+
+ return container;
+ }
+
+ class RequestHandler : IRequestHandler where T : IRequest
+ {
+ private readonly IRequestContext _requestContext;
+
+ public RequestHandler(IRequestContext requestContext)
+ {
+ _requestContext = requestContext;
+ }
+ public Task Handle(T request, CancellationToken cancellationToken)
+ {
+ return ((IRequestHandler) _requestContext.Descriptor.Handler).Handle(request, cancellationToken);
+ }
+ }
+
+ class RequestHandlerDecorator : IRequestHandler where T : IRequest
+ {
+ private readonly IRequestHandler? _handler;
+ private readonly IRequestContext? _requestContext;
+
+ public RequestHandlerDecorator(IRequestHandler? handler = null, IRequestContext? requestContext = null)
+ {
+ _handler = handler;
+ _requestContext = requestContext;
+ }
+ public Task Handle(T request, CancellationToken cancellationToken)
+ {
+ if (_requestContext == null)
+ {
+ if (_handler == null)
+ {
+ throw new NotImplementedException($"No request handler was registered for type {typeof(IRequestHandler).FullName}");
- return container.With(
- rules => rules.WithUnknownServiceResolvers(
- request => {
- if (request.ServiceType.IsGenericType && typeof(IRequestHandler<,>).IsAssignableFrom(request.ServiceType.GetGenericTypeDefinition()))
- {
- var context = request.Container.Resolve();
- if (context != null)
- {
- return new RegisteredInstanceFactory(context.Descriptor.Handler);
- }
- }
-
- return null;
}
- )
- );
+
+ return _handler.Handle(request, cancellationToken);
+ }
+
+ return ((IRequestHandler) _requestContext.Descriptor.Handler).Handle(request, cancellationToken);
+ }
}
internal static IContainer AddJsonRpcServerInternals(this IContainer container, JsonRpcServerOptions options)
diff --git a/src/Protocol/ConfigureByConfigurationPathExtension.cs b/src/Protocol/ConfigureByConfigurationPathExtension.cs
new file mode 100644
index 000000000..336c9e6dd
--- /dev/null
+++ b/src/Protocol/ConfigureByConfigurationPathExtension.cs
@@ -0,0 +1,176 @@
+#if false
+using System;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Configuration.Binder;
+using Microsoft.Extensions.Primitives;
+
+// ReSharper disable once CheckNamespace
+namespace Microsoft.Extensions.Configuration
+{
+ public static class ConfigureByConfigurationPathExtension
+ {
+ ///
+ /// Registers a injected configuration service which TOptions will bind against.
+ ///
+ /// The type of options being configured.
+ /// The to add the services to.
+ /// The so that additional calls can be chained.
+ public static IServiceCollection Configure(this IServiceCollection services)
+ where TOptions : class
+ {
+ if (services == null)
+ {
+ throw new ArgumentNullException(nameof(services));
+ }
+
+ return Configure(services, null);
+ }
+
+ ///
+ /// Registers a injected configuration service which TOptions will bind against.
+ ///
+ /// The type of options being configured.
+ /// The to add the services to.
+ /// The name of the options instance.
+ /// The so that additional calls can be chained.
+ public static IServiceCollection Configure(this IServiceCollection services, string? sectionName)
+ where TOptions : class
+ {
+ if (services == null)
+ {
+ throw new ArgumentNullException(nameof(services));
+ }
+
+ services.AddOptions();
+ services.AddSingleton>(
+ _ => new ConfigurationChangeTokenSource(
+ Options.Options.DefaultName,
+ sectionName == null ? _.GetRequiredService() : _.GetRequiredService().GetSection(sectionName)
+ )
+ );
+ return services.AddSingleton>(
+ _ => new NamedConfigureFromConfigurationOptions(
+ Options.Options.DefaultName,
+ sectionName == null ? _.GetRequiredService() : _.GetRequiredService().GetSection(sectionName)
+ )
+ );
+ }
+
+ ///
+ /// Registers a injected configuration service which TOptions will bind against.
+ ///
+ /// The type of options being configured.
+ /// The to add the services to.
+ /// Used to configure the .
+ /// The so that additional calls can be chained.
+ public static IServiceCollection Configure(this IServiceCollection services, Action configureBinder)
+ where TOptions : class
+ {
+ if (services == null)
+ {
+ throw new ArgumentNullException(nameof(services));
+ }
+
+ return Configure(services, Options.Options.DefaultName, configureBinder);
+ }
+
+ ///
+ /// Registers a injected configuration service which TOptions will bind against.
+ ///
+ /// The type of options being configured.
+ /// The to add the services to.
+ /// The name of the options instance.
+ /// Used to configure the .
+ /// The so that additional calls can be chained.
+ public static IServiceCollection Configure(this IServiceCollection services, string sectionName, Action configureBinder)
+ where TOptions : class
+ {
+ if (services == null)
+ {
+ throw new ArgumentNullException(nameof(services));
+ }
+
+ services.AddOptions();
+ services.AddSingleton>(_ => new ConfigurationChangeTokenSource(Options.Options.DefaultName, _.GetRequiredService().GetSection(sectionName)));
+ return services.AddSingleton>(_ => new NamedConfigureFromConfigurationOptions(Options.Options.DefaultName, _.GetRequiredService().GetSection(sectionName), configureBinder));
+ }
+
+ ///
+ /// Registers a injected configuration service which TOptions will bind against.
+ ///
+ /// The type of options being configured.
+ /// The to configure.
+ /// The so that additional calls can be chained.
+ public static OptionsBuilder Configure(this OptionsBuilder builder)
+ where TOptions : class
+ {
+ if (builder == null)
+ {
+ throw new ArgumentNullException(nameof(builder));
+ }
+
+ return Configure(builder, Options.Options.DefaultName);
+ }
+
+ ///
+ /// Registers a injected configuration service which TOptions will bind against.
+ ///
+ /// The type of options being configured.
+ /// The to configure.
+ /// The name of the options instance.
+ /// The so that additional calls can be chained.
+ public static OptionsBuilder Configure(this OptionsBuilder builder, string sectionName)
+ where TOptions : class
+ {
+ if (builder == null)
+ {
+ throw new ArgumentNullException(nameof(builder));
+ }
+
+ Configure(builder.Services, name);
+ return builder;
+ }
+
+ ///
+ /// Registers a injected configuration service which TOptions will bind against.
+ ///
+ /// The type of options being configured.
+ /// The to configure.
+ /// Used to configure the .
+ /// The so that additional calls can be chained.
+ public static OptionsBuilder Configure(this OptionsBuilder builder, Action configureBinder)
+ where TOptions : class
+ {
+ if (builder == null)
+ {
+ throw new ArgumentNullException(nameof(builder));
+ }
+
+ return Configure(builder, Options.Options.DefaultName, configureBinder);
+ }
+
+ ///
+ /// Registers a injected configuration service which TOptions will bind against.
+ ///
+ /// The type of options being configured.
+ /// The to configure.
+ /// The name of the options instance.
+ /// Used to configure the .
+ /// The so that additional calls can be chained.
+ public static OptionsBuilder Configure(this OptionsBuilder builder, string sectionName, Action configureBinder)
+ where TOptions : class
+ {
+ if (builder == null)
+ {
+ throw new ArgumentNullException(nameof(builder));
+ }
+
+
+ Configure(builder.Services, name, configureBinder);
+ return builder;
+ }
+ }
+}
+#endif
diff --git a/src/Protocol/LanguageProtocolDelegatingHandlers.cs b/src/Protocol/LanguageProtocolDelegatingHandlers.cs
index 2136ca6ee..eba50a456 100644
--- a/src/Protocol/LanguageProtocolDelegatingHandlers.cs
+++ b/src/Protocol/LanguageProtocolDelegatingHandlers.cs
@@ -1088,6 +1088,17 @@ public NotificationCapability(Func handler) :
{
}
+ public NotificationCapability(Action handler) :
+ this(
+ Guid.Empty, (request, capability, ct) => {
+ handler(request, capability, ct);
+ return Task.CompletedTask;
+ }
+ )
+ {
+ }
+
+
public NotificationCapability(Func handler) :
this(Guid.Empty, handler)
{
diff --git a/src/Protocol/Protocol.csproj b/src/Protocol/Protocol.csproj
index 00c78fc5e..0114e9d23 100644
--- a/src/Protocol/Protocol.csproj
+++ b/src/Protocol/Protocol.csproj
@@ -9,6 +9,11 @@
+
diff --git a/src/Protocol/Workspace/IDidChangeConfigurationHandler.cs b/src/Protocol/Workspace/IDidChangeConfigurationHandler.cs
index 7f80e3fa9..789d699e8 100644
--- a/src/Protocol/Workspace/IDidChangeConfigurationHandler.cs
+++ b/src/Protocol/Workspace/IDidChangeConfigurationHandler.cs
@@ -14,15 +14,16 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol.Workspace
[GenerateHandlerMethods]
[GenerateRequestMethods(typeof(IWorkspaceLanguageClient), typeof(ILanguageClient))]
public interface IDidChangeConfigurationHandler : IJsonRpcNotificationHandler,
- IRegistration
+
+
+ MSBuild:GenerateCodeFromAttributes
+
+